久久亚洲成a人片熟女精品色一区二区三区|国产精品视频第一精品视频|av天堂热无码手机版|亚洲?v无码久久无遮挡|国产精品偷伦视频免费观看国产|麻豆国产自产精品丰满熟妇|av无码av不卡一区二区|久久亚洲精品中文字

ARTICLE DETAIL

資訊詳情

深耕商務(wù)建站與企業(yè)官網(wǎng)運(yùn)營(yíng)的一線實(shí)戰(zhàn)洞察。

全棧類型安全新范式:用T3 Stack與tRPC告別前后端聯(lián)調(diào)之痛

全棧類型安全新范式:用T3 Stack與tRPC告別前后端聯(lián)調(diào)之痛 以前搭全棧項(xiàng)目最讓我頭疼的從來(lái)不是功能復(fù)雜度而是前后端之間那層反復(fù)扯皮的類型定義。后端改了字段名前端編譯直接一片紅更別提寫一整套 API 封裝、手搓類型聲明、再對(duì)著文檔排查接口字段的日常。后來(lái)接觸到 t3code 這套基于 T3 Stack 的腳手架工作流我最大的感受是它不是在幫你寫代碼而是在重構(gòu)你組織全棧代碼的方式——把“前后端各寫一套”變成“從一個(gè)類型源頭自動(dòng)派生出整個(gè)調(diào)用鏈路”。這篇文章我就用實(shí)際經(jīng)歷聊聊t3code 到底解決了我哪些真實(shí)痛點(diǎn)里面的技術(shù)選型是怎么協(xié)作的以及從初始化到部署我用它做完兩個(gè)項(xiàng)目后沉淀下來(lái)的經(jīng)驗(yàn)和幾個(gè)躲不開(kāi)的坑。1. 為什么我盯上了 t3code從手寫后端到全棧類型安全的轉(zhuǎn)變1.1 全棧項(xiàng)目最消耗精力的是“共識(shí)維護(hù)”一提到全棧項(xiàng)目很多人第一反應(yīng)是“技術(shù)棧多”“要學(xué)的東西雜”。但我真正做了幾個(gè)商用規(guī)模的 Web 應(yīng)用之后發(fā)現(xiàn)技術(shù)棧復(fù)雜只是入門門檻真正的隱性成本在于前后端對(duì)數(shù)據(jù)結(jié)構(gòu)的共識(shí)怎么維護(hù)。傳統(tǒng)方案里前端通常通過(guò) REST API 和 Vue/React 頁(yè)面打交道我需要維護(hù)一份 API 文檔或者用 OpenAPI/Swagger 描述接口后端改了 User 模型的字段前端必須同步修改 interface。項(xiàng)目一大了這個(gè)同步過(guò)程就會(huì)出現(xiàn)三類問(wèn)題改了后端字段但前端沒(méi)跟上線上頁(yè)面白屏或者取到 undefined接口文檔更新不及時(shí)前端按舊文檔聯(lián)調(diào)浪費(fèi)半天時(shí)間某個(gè)字段從 string 變成 number類型沒(méi)有編譯期報(bào)錯(cuò)導(dǎo)致運(yùn)行期才暴露異常。t3code 的出現(xiàn)有意思在它換了個(gè)思路與其費(fèi)力維護(hù)前后端的類型共識(shí)不如讓后端類型直接生成前端調(diào)用代碼的類型簽名。也就是說(shuō)前端真正調(diào)用的數(shù)據(jù)是從后端那個(gè)唯一的類型源頭“長(zhǎng)”出來(lái)的。1.2 t3code 到底是什么雖然現(xiàn)在網(wǎng)上也有各種以 t3 開(kāi)頭命名的項(xiàng)目但我在實(shí)際開(kāi)發(fā)中使用的 t3code本質(zhì)上是一套面向全棧 TypeScript 項(xiàng)目的腳手架和模塊初始化工具。它圍繞 T3 StackNext.js TypeScript tRPC Prisma Tailwind CSS把項(xiàng)目的基礎(chǔ)骨架、數(shù)據(jù)模型、認(rèn)證體系、API 路由和前后端調(diào)用關(guān)系一次性裝配起來(lái)我拿到手就能直接把精力放到業(yè)務(wù)邏輯上。我自己的體會(huì)是t3code 最適合這幾類人獨(dú)立開(kāi)發(fā)者想用一份 TypeScript 代碼同時(shí)打通數(shù)據(jù)庫(kù)、后端邏輯和前端頁(yè)面小型全棧團(tuán)隊(duì)希望減少前后端聯(lián)調(diào)時(shí)的來(lái)回溝通成本正在搭建 MVP 的創(chuàng)業(yè)項(xiàng)目需要快速迭代數(shù)據(jù)結(jié)構(gòu)且不想被接口設(shè)計(jì)和類型維護(hù)拖慢速度。如果你平時(shí)只是寫純前端或者純后端t3code 的收益不大但如果你做的是那種“一個(gè)人要包圓前后端數(shù)據(jù)庫(kù)”的活它真的能幫你省下很多重復(fù)勞動(dòng)。1.3 它和“低代碼平臺(tái)”完全不是一回事第一次聽(tīng)到這類工具時(shí)我也擔(dān)心過(guò)這會(huì)不會(huì)又是一套低代碼平臺(tái)把我綁定到某個(gè)私有協(xié)議上以后想遷移都沒(méi)法遷移實(shí)際研究過(guò)后我可以明確說(shuō)t3code 不搞任何私有的運(yùn)行時(shí)協(xié)議它輸出的就是一個(gè)標(biāo)準(zhǔn)的 Next.js 項(xiàng)目里面有正常的 Prisma schema、tRPC router、頁(yè)面組件和 API 流程。換句話說(shuō)它幫我完成的是“裝配和初始化”不是“托管和綁架”。項(xiàng)目一旦生成源碼都在我手里所有邏輯都由我自己控制該寫測(cè)試寫測(cè)試、該做性能優(yōu)化做性能優(yōu)化沒(méi)有任何黑盒。1.4 從“寫最少代碼”到“改最少代碼”我用傳統(tǒng)方式做一個(gè)帶用戶系統(tǒng)的內(nèi)容管理后臺(tái)大概要經(jīng)歷設(shè)計(jì)數(shù)據(jù)庫(kù)表結(jié)構(gòu)、寫后端 CRUD 接口、逐一手寫路由和校驗(yàn)、生成前端 API 封裝、在頁(yè)面上手動(dòng)消費(fèi)數(shù)據(jù)、遇到類型不一致再回頭改。整個(gè)流程中真正屬于業(yè)務(wù)邏輯的代碼可能只占 40%剩下 60% 都在做“翻譯”和“適配”工作。t3code 把我從這種狀態(tài)里拉出來(lái)之后我明顯感覺(jué)到工作模式變了。從前是“寫最少代碼完成任務(wù)”現(xiàn)在更像是“盡量少改代碼地演化業(yè)務(wù)”。數(shù)據(jù)庫(kù)加個(gè)字段Prisma 遷移一執(zhí)行類型自動(dòng)更新后端在 tRPC 的 router 里加一個(gè) query前端立刻能在編輯器里拿到帶類型提示的調(diào)用方法甚至參數(shù)結(jié)構(gòu)都是自動(dòng)推導(dǎo)的。這種“一處修改處處類型安全”的體驗(yàn)用一次就回不去。2. t3code 的底層構(gòu)成T3 技術(shù)棧四件套是怎么協(xié)作的2.1 四個(gè)核心依賴各管哪一段t3code 生成的骨架里最核心的是四個(gè)依賴。很多人把它們當(dāng)成單純的技術(shù)組合但我在實(shí)際使用中更關(guān)注它們各自承擔(dān)的角色以及彼此之間的接縫在哪里。一是Next.js負(fù)責(zé)應(yīng)用框架層。它同時(shí)提供 React 頁(yè)面渲染、API Route、服務(wù)端渲染和靜態(tài)生成能力。在 T3 Stack 的語(yǔ)境里Next.js 不僅是一個(gè)頁(yè)面框架更是把前后端放在同一工程里的容器。二是TypeScript整個(gè)項(xiàng)目的類型系統(tǒng)基底。如果沒(méi)有 TypeScript后面講的“端到端類型安全”完全不成立所以我在 t3code 里很少看到 .js 文件所有業(yè)務(wù)代碼和配置文件都以 .ts 或 .tsx 為主。三是tRPC負(fù)責(zé)前后端調(diào)用層的協(xié)議。它不需要我們手寫 REST 路由也不需要生成 GraphQL schema而是直接通過(guò)函數(shù)調(diào)用的方式在前端調(diào)用后端方法并且自動(dòng)獲得完整的類型推導(dǎo)。它的實(shí)現(xiàn)原理不復(fù)雜就是依賴 TypeScript 的泛型把 router 類型直接傳遞到前端 hooks 上。四是Prisma負(fù)責(zé)數(shù)據(jù)模型和數(shù)據(jù)庫(kù)訪問(wèn)。它用一個(gè) schema 文件定義模型然后生成類型安全的客戶端。在 t3code 的項(xiàng)目里Prisma 的 model 是整個(gè)應(yīng)用數(shù)據(jù)結(jié)構(gòu)的直接描述者。至于 Tailwind CSS我一般把它看成錦上添花的樣式方案它解決的是 UI 層開(kāi)發(fā)效率的問(wèn)題不影響類型閉環(huán)。2.2 類型閉環(huán)是怎么走通的要真正理解 t3code 的價(jià)值我建議你先搞清楚這條類型閉環(huán)的路徑Prisma schema 定義模型 ↓ Prisma Client 生成類型 ↓ tRPC router 里用這些類型處理輸入輸出 ↓ 前端通過(guò) tRPC hooks 調(diào)用 router ↓ 編輯器根據(jù)推導(dǎo)自動(dòng)提示類型和參數(shù)我把這條鏈路拆開(kāi)講一下。假設(shè)我在prisma/schema.prisma里定義一個(gè)Todo模型model Todo { id String id default(cuid()) title String completed Boolean default(false) createdAt DateTime default(now()) }執(zhí)行npx prisma migrate dev之后Prisma 客戶端會(huì)生成對(duì)應(yīng)的Todo類型。接著在 tRPC router 中加入一個(gè)返回所有待辦事項(xiàng)的查詢import { router, publicProcedure } from ../trpc; import { prisma } from ../db; export const todoRouter router({ getAll: publicProcedure.query(() { return prisma.todo.findMany(); }), });前端頁(yè)面里我不需要重新定義任何 interface直接調(diào)用import { api } from ~/utils/api; export default function TodoList() { const { data: todos } api.todo.getAll.useQuery(); return ( ul {todos?.map((todo) ( li key{todo.id}{todo.title}/li ))} /ul ); }這里你會(huì)發(fā)現(xiàn)一個(gè)有意思的地方todos的類型是由后端 Prisma 查詢結(jié)果推導(dǎo)出來(lái)的而不是我手動(dòng)聲明的。哪怕哪天我往模型里加了字段前端代碼里todo.someNewField也馬上會(huì)有類型提示如果我刪了某個(gè)字段前端用到它的地方會(huì)直接編譯報(bào)錯(cuò)。這條閉環(huán)的意義在于它把“類型正確性”從一種約定變成了一種編譯期保證。我不用再擔(dān)心“前端不知道后端字段改過(guò)”這種事因?yàn)轭愋拖到y(tǒng)會(huì)第一時(shí)間攔住我。2.3 和 REST / GraphQL 方案的直觀對(duì)比我知道有人會(huì)問(wèn)我用 REST 加 OpenAPI 也能生成類型用 GraphQL 也能自動(dòng)推導(dǎo)為什么非要用 t3code 這一套我做了一張粗淺的對(duì)照表完全基于我的日常體感方案類型安全性聯(lián)調(diào)成本學(xué)習(xí)曲線適用場(chǎng)景REST 手寫類型靠自覺(jué)高低傳統(tǒng)前后端分離團(tuán)隊(duì)REST OpenAPI 生成類型中中中接口規(guī)范嚴(yán)格的團(tuán)隊(duì)GraphQL Codegen高低高需要靈活查詢的大前端團(tuán)隊(duì)t3codeT3 Stack高很低中全棧 TypeScript 項(xiàng)目、獨(dú)立開(kāi)發(fā)者GraphQL 雖然查詢能力很靈活但為了拿到這種靈活性我得維護(hù) schema、寫 resolver、配 codegen還要考慮客戶端緩存策略對(duì)一個(gè)人干全棧來(lái)說(shuō)其實(shí)不輕。t3code 里 tRPC 的模型更“純函數(shù)式”前端調(diào)用后端的體驗(yàn)幾乎等于調(diào)用本地函數(shù)而且不用額外跑代碼生成器類型推導(dǎo)是實(shí)時(shí)的。當(dāng)然 tRPC 也有自己的適用范圍——如果前后端完全分離且由不同團(tuán)隊(duì)維護(hù)或者需要對(duì)外提供公共 APItRPC 反而不合適。它更多是內(nèi)部后端和前端之間的一種高效溝通方式。選型永遠(yuǎn)要基于項(xiàng)目形態(tài)t3code 適合的是“一個(gè)代碼庫(kù)搞定全?!钡膱?chǎng)景。3. 跑通第一個(gè) t3code 項(xiàng)目從初始化到 CRUD 的完整鏈路3.1 初始化項(xiàng)目時(shí)該選哪些模塊t3code 的起點(diǎn)是create-t3-app這個(gè)命令。我在終端執(zhí)行npx create-t3-applatest my-app交互式命令行會(huì)問(wèn)你項(xiàng)目名稱、要不要啟用 NextAuth.js、Prisma、Tailwind CSS、tRPC 這些模塊以及使用 npm 還是 pnpm 等包管理器。我第一次跑的時(shí)候很老實(shí)把能勾選的全都勾上了。后來(lái)實(shí)際開(kāi)發(fā)才意識(shí)到不必為了齊全而全選要根據(jù)業(yè)務(wù)預(yù)判來(lái)選。我現(xiàn)在的選擇習(xí)慣是一定會(huì)選 TypeScript、Prisma、tRPC、Next.js這是核心需要用戶登錄時(shí)才會(huì)勾選 NextAuth.js如果只是內(nèi)部系統(tǒng)且不涉及用戶體系不選它反而省事Tailwind CSS 純看項(xiàng)目 UI 需求如果團(tuán)隊(duì)已經(jīng)定了組件庫(kù)或者用其他 CSS 方案就不必讓它進(jìn)入代碼庫(kù)部署平臺(tái)選擇 Vercel 時(shí)腳手架會(huì)順便把本地開(kāi)發(fā)和生產(chǎn)環(huán)境的配置處理好選 Docker 自托管的話后面要自己留意數(shù)據(jù)庫(kù)連接。初始化完成后項(xiàng)目的目錄結(jié)構(gòu)大概是這樣的my-app/ ├── prisma/ │ └── schema.prisma ├── src/ │ ├── pages/ │ ├── server/ │ │ ├── api/ │ │ │ └── trpc/ │ │ ├── auth.ts │ │ └── db.ts │ └── utils/ │ └── api.ts ├── .env └── package.json這里src/server/db.ts是 Prisma Client 單例src/utils/api.ts是前端 tRPC hooks 的封裝入口src/server/api/trpc.ts定義了 router 創(chuàng)建和 procedure 的基礎(chǔ)。我建議拿到項(xiàng)目后先花十分鐘把這三個(gè)文件讀一遍理解它們之間的引用關(guān)系后面寫業(yè)務(wù)會(huì)順很多。3.2 從 schema 到數(shù)據(jù)庫(kù)遷移我拿一個(gè)最簡(jiǎn)單的博客系統(tǒng)舉例。先在prisma/schema.prisma里定義 Post 和 User 模型model User { id String id default(cuid()) email String unique name String? posts Post[] } model Post { id String id default(cuid()) title String content String published Boolean default(false) authorId String author User relation(fields: [authorId], references: [id]) createdAt DateTime default(now()) updatedAt DateTime updatedAt }然后執(zhí)行npx prisma migrate dev --name init這個(gè)命令會(huì)做兩件事在數(shù)據(jù)庫(kù)里創(chuàng)建對(duì)應(yīng)的表同時(shí)生成最新版的 Prisma Client。我提醒一句本地?cái)?shù)據(jù)庫(kù)連接串記得先寫進(jìn).env很多人第一次跑 migrate 失敗都是因?yàn)榄h(huán)境變量沒(méi)配置。3.3 編寫 tRPC router 并注冊(cè)接著我在src/server/api/root.ts或其他你自定義的 router 聚合文件里添加一個(gè) postRouterimport { z } from zod; import { createTRPCRouter, publicProcedure } from ~/server/api/trpc; import { prisma } from ~/server/db; export const postRouter createTRPCRouter({ list: publicProcedure.query(() { return prisma.post.findMany({ orderBy: { createdAt: desc }, }); }), byId: publicProcedure .input(z.object({ id: z.string() })) .query(({ input }) { return prisma.post.findUnique({ where: { id: input.id }, include: { author: true }, }); }), create: publicProcedure .input( z.object({ title: z.string().min(1), content: z.string().min(1), authorEmail: z.string().email(), }) ) .mutation(async ({ input }) { const user await prisma.user.upsert({ where: { email: input.authorEmail }, update: {}, create: { email: input.authorEmail, name: input.authorEmail.split()[0] }, }); return prisma.post.create({ data: { title: input.title, content: input.content, authorId: user.id, }, }); }), });這里你可能注意到我用了 zod 做輸入校驗(yàn)。tRPC 原生建議用 zod 作為 schema 校驗(yàn)庫(kù)它和 tRPC 的 input 結(jié)合非常好。輸入校驗(yàn)不僅保證了后端接口的參數(shù)安全還讓前端調(diào)用時(shí)能拿到準(zhǔn)確的入?yún)㈩愋吞崾舅闶穷愋烷]環(huán)里的重要一環(huán)。寫完之后必須把 postRouter 注冊(cè)到根 router 上否則前端根本訪問(wèn)不到import { createTRPCRouter } from ~/server/api/trpc; import { postRouter } from ./post; export const appRouter createTRPCRouter({ post: postRouter, }); export type AppRouter typeof appRouter;3.4 前端頁(yè)面消費(fèi) API前端頁(yè)面直接對(duì)應(yīng)src/pages/index.tsx我用一個(gè)列表頁(yè)展示所有文章import { api } from ~/utils/api; import Link from next/link; export default function Home() { const { data: posts, isLoading } api.post.list.useQuery(); if (isLoading) return divLoading.../div; return ( div {posts?.map((post) ( Link key{post.id} href{/post/${post.id}} h2{post.title}/h2 p{post.content}/p /Link ))} /div ); }刷新頁(yè)面后數(shù)據(jù)就能正常渲染。我沒(méi)寫任何額外的 axios 封裝沒(méi)有手動(dòng)拼 URL沒(méi)有定義 response interface甚至連useQuery的泛型都不用傳類型全是從后端推導(dǎo)過(guò)來(lái)的。這個(gè)“少寫代碼但類型更強(qiáng)”的體驗(yàn)就是我前面說(shuō)的核心價(jià)值。如果想做創(chuàng)建文章的交互也很直接const createPost api.post.create.useMutation({ onSuccess: () { utils.post.list.invalidate(); }, }); createPost.mutate({ title: 新文章, content: 正文內(nèi)容, authorEmail: testexample.com, });用invalidate讓列表重新請(qǐng)求一次數(shù)據(jù)自動(dòng)刷新前端邏輯保持得非常干凈。3.5 雙向綁定與 SSR 模式的一點(diǎn)提醒t3code 默認(rèn)會(huì)用 Next.js 的 SSR/SSG 能力來(lái)預(yù)取 tRPC 數(shù)據(jù)。也就是說(shuō)服務(wù)端會(huì)先主動(dòng)調(diào)用 tRPC 方法把數(shù)據(jù)塞進(jìn)頁(yè)面 props 里瀏覽器端再用同一個(gè) hook 做水合。這套機(jī)制讓首屏加載很快也不會(huì)有白屏閃爍。但這里的隱性前提是服務(wù)端調(diào)用和客戶端調(diào)用共享同一套 tRPC 邏輯。如果你在 procedure 里訪問(wèn)了只存在于瀏覽器端的window或者localStorage服務(wù)端執(zhí)行時(shí)就會(huì)直接報(bào)錯(cuò)。我建議你從第一天開(kāi)始就養(yǎng)成習(xí)慣把涉及瀏覽器環(huán)境變量的邏輯放到獨(dú)立的工具函數(shù)里并且用typeof window ! undefined判斷環(huán)境不然部署到 Vercel 上很容易踩 SSR 相關(guān)的坑。4. 接入認(rèn)證和數(shù)據(jù)庫(kù)之后我踩過(guò)的那些坑4.1 NextAuth.js 和 Prisma 的適配器問(wèn)題t3code 腳手架雖然默認(rèn)集成了 NextAuth.js但真正接入登錄功能時(shí)我遇到的第一坑是適配器adapter的配置。NextAuth 要跟 Prisma 配合必須用next-auth/prisma-adapter并且在src/server/auth.ts里正確傳參。如果適配器沒(méi)配好最常見(jiàn)的報(bào)錯(cuò)是調(diào)用登錄接口時(shí)數(shù)據(jù)庫(kù)無(wú)法寫入 session 記錄。我當(dāng)時(shí)的排查過(guò)程是這樣的先看服務(wù)端日志確認(rèn)是 session 表寫入失敗再看auth.ts里的配置發(fā)現(xiàn)adapter沒(méi)有被傳入。修正后的核心代碼大致是import NextAuth from next-auth; import CredentialsProvider from next-auth/providers/credentials; import { PrismaAdapter } from next-auth/prisma-adapter; import { prisma } from ~/server/db; export const authOptions { adapter: PrismaAdapter(prisma), providers: [ CredentialsProvider({ name: credentials, credentials: { email: { label: Email, type: email }, password: { label: Password, type: password }, }, async authorize(credentials) { // 這里是校驗(yàn)邏輯 }, }), ], session: { strategy: jwt, }, secret: process.env.NEXTAUTH_SECRET, };接下來(lái)還有一個(gè)容易忽視的點(diǎn)如果用默認(rèn)的strategy: jwt就不太依賴數(shù)據(jù)庫(kù)里的 session 記錄這時(shí) PrismaAdapter 需要同步維護(hù)的其實(shí)是 User、Account、Session 等模型。我在 schema 里如果漏了這些模型登錄時(shí)也會(huì)因?yàn)閿?shù)據(jù)庫(kù)缺表而出錯(cuò)。解法很簡(jiǎn)單把官網(wǎng)文檔里提供的 NextAuth 相關(guān)模型復(fù)制到schema.prisma再跑一次遷移問(wèn)題基本就解決了。4.2 環(huán)境變量缺失導(dǎo)致的“幽靈報(bào)錯(cuò)”t3code 初始化后項(xiàng)目根目錄會(huì)生成一個(gè).env文件里面通常會(huì)預(yù)留DATABASE_URL、NEXTAUTH_SECRET、NEXTAUTH_URL這些變量。我最開(kāi)始忽略了一點(diǎn)本地開(kāi)發(fā)和生產(chǎn)環(huán)境需要不同取值。比如本地.env里DATABASE_URL指向localhost的 PostgreSQL生產(chǎn)環(huán)境在 Vercel 后臺(tái)配的卻是線上數(shù)據(jù)庫(kù)地址。如果你在本地跑prisma migrate deploy時(shí)用錯(cuò)了環(huán)境變量有可能把遷移應(yīng)用到線上或者本地庫(kù)上那將是災(zāi)難。我的建議是給不同環(huán)境配獨(dú)立的.env文件如.env.local、.env.production并且永遠(yuǎn)只在項(xiàng)目目錄里執(zhí)行數(shù)據(jù)庫(kù)遷移命令。雖然這屬于老生常談但團(tuán)隊(duì)協(xié)作時(shí)真的有人會(huì)把線上連接串寫到公共配置里導(dǎo)致泄露。4.3 protectedProcedure 的正確姿勢(shì)t3code 腳手架通常會(huì)提供一個(gè)createTRPCContext函數(shù)把當(dāng)前請(qǐng)求的 session 塞進(jìn) context。我后來(lái)在寫需要登錄才能調(diào)用的接口時(shí)沒(méi)用publicProcedure而是基于 context 判斷后再拋錯(cuò)export const protectedProcedure t.procedure.use(({ ctx, next }) { if (!ctx.session || !ctx.session.user) { throw new Error(Unauthorized); } return next({ ctx: { session: { ...ctx.session, user: ctx.session.user }, }, }); });這個(gè)中間件做完之后我想獲取當(dāng)前用戶時(shí)直接讀ctx.session.user就行。前端調(diào)用時(shí)配合useSession()判斷登錄態(tài)體驗(yàn)整體很順。我踩過(guò)的坑是如果 session 類型沒(méi)和數(shù)據(jù)庫(kù)的 User 模型對(duì)齊前端拿到的session.user.id可能被推導(dǎo)成string | undefined導(dǎo)致一些危險(xiǎn)的隱性 bug——比如在創(chuàng)建 Post 時(shí)把 undefined 寫進(jìn) authorId。所以建議大家拿到 session 后先做一次顯式判空再往下走。4.4 CRUD 校驗(yàn)放在服務(wù)端不要在客戶端省事tRPC 的好處是輸入校驗(yàn)天然寫在服務(wù)端 procedure 里但我見(jiàn)過(guò)有些同事圖方便只在前端表單里做了校驗(yàn)后端換個(gè)請(qǐng)求工具直接把非法字段傳進(jìn)去。說(shuō)實(shí)話因?yàn)?tRPC 的類型推導(dǎo)太舒服了人很容易產(chǎn)生“前端類型安全等于接口安全”的錯(cuò)覺(jué)。實(shí)際上類型安全不等于安全。zod 校驗(yàn)?zāi)菍臃谰€必須留在服務(wù)端。我在 t3code 項(xiàng)目里的習(xí)慣是所有涉及寫入的操作一律寫 zod input schema并且把z.string().min(1)這類邊界條件寫全。這樣即使有人繞過(guò)前端調(diào)后端數(shù)據(jù)也會(huì)被攔截在這層不會(huì)污染數(shù)據(jù)庫(kù)。5. 部署與優(yōu)化從開(kāi)發(fā)機(jī)到生產(chǎn)環(huán)境的最后一公里5.1 部署到 Vercel 前要處理的事情t3code 生成的 Next.js 項(xiàng)目直接對(duì)接 Vercel 很方便。我第一次部署時(shí)只把 GitHub 倉(cāng)庫(kù)連到 Vercel然后添加環(huán)境變量就完事了。但后來(lái)發(fā)現(xiàn)有幾個(gè)細(xì)節(jié)要提前準(zhǔn)備好否則很容易在線上出現(xiàn)詭異問(wèn)題。第一Prisma Client 的生成時(shí)機(jī)。Vercel 構(gòu)建時(shí)會(huì)跑prisma generate但只在構(gòu)建環(huán)境里生成如果你本地的 Prisma Client 版本和線上不一致有可能導(dǎo)致運(yùn)行時(shí)錯(cuò)誤。我一般會(huì)在package.json的postinstall腳本里加上postinstall: prisma generate這樣每次裝完依賴都會(huì)從 schema 重新生成客戶端不會(huì)出現(xiàn)版本漂移。第二數(shù)據(jù)庫(kù)遷移怎么執(zhí)行。Vercel 的構(gòu)建環(huán)境不是跑遷移的好地方我推薦用 GitHub Actions 或一個(gè)獨(dú)立的環(huán)境去跑prisma migrate deploy。也就是說(shuō)代碼部署和數(shù)據(jù)庫(kù)遷移分成兩個(gè)流程代碼先發(fā)布遷移單獨(dú)控制節(jié)奏。這樣做的好處是一旦遷移失敗不會(huì)把應(yīng)用構(gòu)建直接拖死。第三NEXTAUTH_URL 必須和生產(chǎn)域名一致。NextAuth 在做回調(diào)時(shí)會(huì)校驗(yàn)這個(gè)變量我見(jiàn)過(guò)不少案例是由于把它留成http://localhost:3000導(dǎo)致線上登錄后跳轉(zhuǎn)回本地地址表現(xiàn)為“登錄成功但立刻又跳回登錄頁(yè)”。這個(gè)坑排查起來(lái)其實(shí)不難但確實(shí)很耗時(shí)間。5.2 Serverless 環(huán)境下的數(shù)據(jù)庫(kù)連接池Vercel 的 Serverless 函數(shù)是“按請(qǐng)求拉起、跑完即回收”的模型。如果我在每個(gè)函數(shù)實(shí)例里都創(chuàng)建一個(gè)新的 Prisma Client 連接很快會(huì)把數(shù)據(jù)庫(kù)連接數(shù)打滿尤其在使用 PostgreSQL 時(shí)特別明顯。t3code 生成的src/server/db.ts里幫我做了一個(gè)全局單例import { PrismaClient } from prisma/client; const globalForPrisma globalThis as unknown as { prisma: PrismaClient }; export const prisma globalForPrisma.prisma ?? new PrismaClient({ log: process.env.NODE_ENV development ? [query, error, warn] : [error], }); if (process.env.NODE_ENV ! production) globalForPrisma.prisma prisma;這個(gè)模式的核心意圖是在本地開(kāi)發(fā)時(shí)熱更新會(huì)導(dǎo)致模塊反復(fù)加載如果不做全局緩存每次刷新都會(huì)創(chuàng)建新的 Prisma 實(shí)例部署到 Serverless 環(huán)境后同一實(shí)例內(nèi)部復(fù)用連接。我在生產(chǎn)環(huán)境跑了一段時(shí)間后數(shù)據(jù)庫(kù)連接數(shù)一直保持在一個(gè)健康水位。如果項(xiàng)目流量上來(lái)還可以在數(shù)據(jù)庫(kù)連接串里加上連接池參數(shù)比如 Prisma 官方建議的?pgbouncertrue配合 PgBouncer 使用。要不要這樣做取決于實(shí)際并發(fā)量我自己的經(jīng)驗(yàn)是中小型應(yīng)用把單例模式做好就夠用了等連接數(shù)告警了再上連接池也不遲。5.3 首屏性能調(diào)優(yōu)的幾個(gè)實(shí)際操作雖然 t3code 的默認(rèn)體驗(yàn)已經(jīng)不錯(cuò)但生產(chǎn)環(huán)境對(duì)性能的要求更高。我做過(guò)的幾個(gè)有效優(yōu)化排在這里按需取數(shù)據(jù)Prisma 的select和include要按頁(yè)面需要來(lái)避免一次findMany把幾十個(gè)字段全撈出來(lái)。Serverless 函數(shù)的執(zhí)行時(shí)間就是錢數(shù)據(jù)量小一點(diǎn)響應(yīng)自然快。開(kāi)啟 Next.js 的緩存策略對(duì)于不常變的數(shù)據(jù)可以用staleTime控制 tRPC 查詢的緩存時(shí)長(zhǎng)。例如文章列表五分鐘內(nèi)不重新請(qǐng)求api.post.list.useQuery(undefined, { staleTime: 5 * 60 * 1000, });嚴(yán)格區(qū)分動(dòng)態(tài)和靜態(tài)頁(yè)面博客首頁(yè)、關(guān)于頁(yè)這種內(nèi)容基本不變的盡量用靜態(tài)生成用戶中心這種強(qiáng)個(gè)性化的頁(yè)面再走 SSR 或客戶端渲染。能靜態(tài)就不動(dòng)態(tài)能讓邊緣緩存接住就讓它接住。5.4 日志、監(jiān)控和錯(cuò)誤上報(bào)做全棧項(xiàng)目時(shí)日志是最容易被忽略但又最重要的一環(huán)。t3code 腳手架只給了基礎(chǔ)結(jié)構(gòu)不包含任何監(jiān)控。我后來(lái)接了一款錯(cuò)誤監(jiān)控工具把 tRPC 的 errors 統(tǒng)一上報(bào)因?yàn)?tRPC 的錯(cuò)誤信息非常規(guī)范有code、message、path這些字段非常適合直接對(duì)接到監(jiān)控平臺(tái)上。我在src/server/api/trpc.ts的 errorFormatter 里做了一次全局?jǐn)r截export const t initTRPC.contexttypeof createTRPCContext().create({ errorFormatter({ shape, error }) { // 在這里上報(bào)錯(cuò)誤 return shape; }, });這樣線上如果出現(xiàn) Zod 校驗(yàn)失敗、數(shù)據(jù)庫(kù)異常、未授權(quán)訪問(wèn)我都能第一時(shí)間從監(jiān)控后臺(tái)看到具體是哪個(gè) procedure 出了問(wèn)題而不需要等用戶反饋。6. 回顧 t3code 這段時(shí)間的實(shí)際體驗(yàn)用 t3code 做了完整項(xiàng)目之后我有個(gè)很直接的感覺(jué)它把全棧開(kāi)發(fā)里的“隱形稅”砍掉了一大半。以前我要花很多時(shí)間維護(hù)前后端接口文檔、類型聲明、API 封裝現(xiàn)在這些成本降到了接近零寫業(yè)務(wù)代碼的密度變得很高。對(duì)我來(lái)說(shuō)它最大的價(jià)值不在代碼生成而在那套類型閉環(huán)帶來(lái)的心智負(fù)擔(dān)減輕。當(dāng)然它也不是銀彈。如果你的團(tuán)隊(duì)前后端完全分離后端需要面向第三方開(kāi)放 API那 tRPC 這套“服務(wù)端和客戶端強(qiáng)綁定”的方式反而會(huì)成為負(fù)擔(dān)。另外T3 Stack 的生態(tài)相對(duì)年輕很多企業(yè)級(jí)基礎(chǔ)設(shè)施的兼容方案需要自己探索比如前面說(shuō)的連接池、多環(huán)境數(shù)據(jù)庫(kù)遷移、CI/CD 流程都需要你額外搭建。但如果你是單兵作戰(zhàn)或者小團(tuán)隊(duì)想做一個(gè)類型安全、可快速迭代的 Web 應(yīng)用t3code 這套工作流非常值得試一下。剛開(kāi)始上手時(shí)多花一點(diǎn)時(shí)間把 Prisma schema、tRPC router、NextAuth 的關(guān)系理解透后續(xù)開(kāi)發(fā)體驗(yàn)的提升會(huì)大大超出你的預(yù)期。最后再分享一個(gè)小技巧。我用 t3code 時(shí)習(xí)慣把項(xiàng)目里所有數(shù)據(jù)庫(kù)寫入操作收斂到mutation里并且做好輸入校驗(yàn)和結(jié)果類型聲明。這樣一旦業(yè)務(wù)邏輯要調(diào)整改動(dòng)范圍會(huì)非常小不會(huì)在十幾個(gè)頁(yè)面里到處找散落的 set 調(diào)用。這種習(xí)慣配合 t3code 的類型推導(dǎo)讓整個(gè)項(xiàng)目即使經(jīng)過(guò)幾個(gè)月的迭代依然保持著比較好的可維護(hù)性。如果你正準(zhǔn)備上手一個(gè)新的全棧項(xiàng)目我建議你從最小閉環(huán)開(kāi)始——先不急著一次性引入全部模塊把列表查詢和一條數(shù)據(jù)寫入跑通感受一下“類型自己長(zhǎng)腳走完全?!钡捏w驗(yàn)再做后續(xù)擴(kuò)展也不遲。
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
亚洲欧美伦综合| 国产粉嫩出水在线播放| 秋霞福利网| AA丁香综合激情| 国产精品嫩草久久久久| 中文?日韩?免费?精品| 亚州春色| 91网亚洲| 日本人体九九九九九九| 国产午夜无码片在线观看影视| 综合久久久久久久综合网| 久草电影网| 九一屌逼| 超碰国产情侣自拍网| 天天天天天天天天天天干美女| 欧美天天在线| 草草草草视频| 少妇人妻在线| 美女黄色91| 激情综合亚洲| 人人操人人爽人人操人人| 麻豆色约约| 午夜九九| 色臀AV| 国产欧美后入| 91精品国产长腿丝袜美女| 天天干天天日天天射黄色大片| 天堂性色| 日韩视频中文字幕| 亚洲阿v天堂在线| 97天天操| 9国产超碰| 97伦综合| 另类图片欧美激情综合| 午夜一区二区三区国产| 久久久夜夜嗨免费视频| 婷婷丁香五月激情啪啪| 中文字幕91综合| 五月天啪啪| 丁香五月色情| 久久最新视频免费观看| 婷婷另类小说| 96久久久精品| 欧美性高潮| 青青草原av| 欧洲一区二区三区四区在线观看| 天天干一区二区| 高清无码网址| 日本熟妇色熟妇在线视频播放| 丁香五月综合| 国产亚洲 中文欧美久久| 久久久久久亚洲精品不卡人乳| 国产视频一区二区三区在线免费观看 | 天天综合~91| 伊人五月天婷婷| 久久美女国产| 精品久久久久黄少妇| 国产激情在线观看| 亚洲超碰AV| 国产 热久久久久国产精品| 亚洲熟女精品| 亚卅熟女乱色| 久久久亚洲精品电影免费看| 性交一区二区在线播放| 欧美日韩精品久久久久久久久东北老熟妇 | 真实高潮91| 丝袜综合色图| 91亚洲黄色网| 午夜福利激情在线视频| 精品97精品97| 怡春院久久| 91东北熟女| 福利操逼| 99青草| 国产婷婷一区| 91性感在线| 中文字幕av亚洲精品| 91久久九九精品国产综合| 欧美成人四级在线播放| 日日狠狠久久偷偷色综合免费| 蜜乳AV一区二区三区四| 丁香五月偷拍| 久久m| 欧美亚洲在线| 一区操逼日比视频| 青操影院| 无码最新| 国产天天骚| 精品综合久久久久久97| 秋霞一集毛片观看| 亚洲天堂中文字幕无码男同| 蜜臀一二三区| 精品少妇99| 91精品微拍福利| 综合久久婷婷| 青青草中日韩在线| www网站黄| 亚洲成人一二三区| 男人久久天堂| 久热9| 人人操人人精品影片| 国产美女口爆吞精视频| 女色视频社区| 日本2020一区二区| 嫖老熟女A片一二三区| 麻豆区99999| 91n处女在线观看| 殴美在线AⅤ| 亚洲自拍一区夜夜操| 91性色| 国产在线76页| 亚洲丝袜少妇在线| 日韩av乱伦| 俺去啦自拍| 狠狠色狠狠色狠狠五月| 亚洲性综合| 天天摸夜夜添无码小视频| 干B| 9Ⅰ超碰| 日韩99神马视频播放| 丝袜综合网| 无码欧美有限公司| 五月天色图| 国产中文字幕曰本毛片| av爱爱爱| 五十路六十路素人熟女| 人人摸人人入| 国内毛片国产欧美拍| 九七色图| 欧美欧美啪啪视频| 欧美黄色手机在线观看| 明星性猛交ⅹxxx乱大交| 女生久久网| 亚州男人天堂| 91露脸熟女专区| 日韩亚洲精品一区二区| 333kkkk·亚洲com久久| 超碰免费人人| 亚洲无992tv| 亚洲风情在线观看| 性饥渴少妇av无码毛片| 亚洲 日韩 丝袜 熟女 变态| 天天干,夜夜爽| 亚洲中文字幕妇伦久久| 骚人妻少妇视频| 色欲天香天天综合网-成年人三级片网站-欧美乱妇狂野-日韩国产专区-久久久久久 | 青椒国产97在线熟女| 琪琪精品免费一区二区三区| 久久欧美性爱视频| 久久国产精品91| 伊人久久大香蕉线AV五月天| 国产精品高朝久久久久久久| 国产精品网址| 欧美猛交黑寡妇中文字幕| 丰满人妻一区二区三区在线| 91久久久久久久| 欧美激情专区| 五月丁香婷婷综合网| 91久青| 欧洲精品网| 91操熟女| 婷婷综合伊人一区| 99福利社| 97视频在线视频| 长长久久免费视频| 精品人妻一区二区三区-国产精品| 欧美色图亚洲色| AAAA级日本片免费视频| 亚洲性爱无码乱伦av| 99色在线| 日本十八禁免费看污网站| 好湿好紧好爽 视频| 日韩天堂av电影在线观看| 九9热伊人| 亚洲无码精品AV久久久| 色五月婷婷麻豆在| 五月天伊人网| 992这里有精品| 欧美综合色综合| 韩国成人精品久久久免费看| 综合网~91综合网| 久96热在线观看视频| 久久久久13| 啪啪啪亚欧美视频| 久热69九色熟妇97| 色吧5亚洲| 欧洲中文字幕| 一本精品日本在线视频精品| 无码久| 日韩卡一卡二卡三在线| 久久黄片国产一区二区| 嗯啊啊啊轻点视频| 亚洲制服aⅴ中文字幕| 久久久久久9999| 亚洲高清国产理伦片| 色偷综合| 黄页大片在线观看| 亚洲av影音先锋| 日本五区不卡| 在线 亚洲 网爆 自拍| 国产精品白丝在线播放 | 强奸xx国产| 九九九999久久久网站| 囯产精品一区二区三区线|亚洲人成无码网WWW动漫|国产精品免费一级... | 福利风月五月天影院| 日韩精品人妻| 国产性爱在线视频一区二区| 久9爱经典视频| 男人的天堂2019AV| 成人性爱美曰韩| 熟女人妻一区二区三区免费看 | 6080YYY午夜理论片在线观看| 国产探花精品在线| 搡老女人老91二区| 91九九九逼| 91婷婷| 男女做爰猛烈动高潮A片免费应用 少妇厨房愉情理伦片bd在线观看 不卡中文字幕aⅴ在线 | 夜夜爽夜夜摸夜夜操免费视频| 国产精品视屏| 97久久久久| 久久综合精品一区二区三区| 亚洲欧洲国产综合av| 91人妻人人澡人人爽人人精品| 亚洲综合色网| 丁香色五月 97干| 先锋影音av先锋一区| 日韩欧美女求操每天更新| 大香蕉欧美国产日韩高潮| 欧美亚性天堂| 啊啊啊啊啊在线观看网址| 色爱三区| 五月丁香大香蕉| 无码视频黄色网战| 欧美成人性爱视频大全| 国产极品美女高潮无套在线观看| 欧美狠狠弄| 欧美淫穴| 欧美最婬乱婬爆婬性视频 | 91视频综合在线| 天操老女人| 免费看污网址| 国内成人圈中文字幕无码视频 | 国产日韩精品人妻久久久久色欲网站| 操操操操网黑人| 狠狠图片青青草| 亚洲成人精品久久久| 在线97在线| 天天色怡春院| 日日爽熟女| 日韩91网站| 日婷婷| 亚洲最新中文字幕免费| 91狠狠综合久久| 久久久久骚| 蜜桃视频啊啊啊啊| 天天综合网合集91| 国产97在线视频| 自拍偷拍第26| 中文字幕一区日韩精| 亚洲成av人片色午夜乱码| 97九色人妻| 日韩av熟女一区二区三区成人| 约操熟妇| 亚洲AV免费在线观看| 国产地址二三| 特色a在线上| 天天激情综合站| 天天干人妇| 99精品热| 18禁看网站一区| 久久久亚洲精品电影免费看| 蜜桃色院一区久久| 欧美激情激情xxxx欧美专区| 狠狠操狠狠爱| 男女啊啊啊啊啊| 日逼国产| 久草线上视频免费看| 八戒午夜福利理论片| 欧美成人A天堂片在线观看| 制服乱伦| 亚洲男人的天堂va亚洲男人社| 91爱看| 无码久久亚洲高清,| 91狠狠| 免費黃色視頻觀看一| 国产偷人妻精品一区二区在线| 久久超碰免费的| BBBBB97COM| 日本欧美一区二区三区免费| 综合激情一一91| 2019天天干天天操| 一级性爱视频免费观看 | 久草综合京东| 乱性AV| 大香蕉十区| 国产强奸乱伦xd| 国产熟女精品区| 欧美成人黄网色网站| 智利AV在线网| 日本韩国一本产品小视频日本韩国一本产品久久久产品小视频日本韩国一本产品久 | 亚洲国产成人7777| 美女91av| yazhousetuoumei| 日韩乱中文 | 国产精品午夜AV完会免费| 18禁止看精品中文字幕| 久久曰曰| 青青草天天亲夜夜操网| 日本男人天堂| 超碰在线欧美性爱激情| 超清中文乱码字幕| 国产日韩欧美中文在线播放| 伊人久久国产免费观看视频| 亚洲日韩精品久久久久一区壹牛| 91国产大片| 欧美久久人体| 日韩欧美tv一区二区在线观看| 青青操日韩| 人妻少妇色综合| 日本五十路在线| 自拍欧美| 1区2区3区视频| 一块操欧美性爱| 国产精品在线免费| 九九天堂| 久久6热视频免费观看| 亚洲宗合网| 五月婷在线| 青草成人免费视频一com| 第二页中文字幕| 亚欧毛片基地国产毛片基地| 欧美人人天天网| 亚洲超碰AV| 亚洲双插| 99热导航| 色色99| 人人搞人人插人人操| 人妻少妇色综合| 欧美很很操视频| 91少妇人妻| 99xav| 蜜臀99999| 日韩成人网址| 国内毛片婷婷六月色| 怡红院成人视频| 日韩精品人妻中文字幕有码午| 操逼片国产| 超碰在线日韩一区| 国产农村妇女精品一二区| 日韩黄色一区二区三区| 日本不卡一区| 中文字幕第7页| 一区二区 日韩 欧美 国产 传媒| 东京热伊久| 在线天堂999| 人妻AV在线| 99精品视频在线观看免费| 性夜影院爽黄A爽免费动漫| 射丝袜大香蕉| 99只有精品| 清柠毛片| 又黑又大又粗| 亚洲第一综合| 日韩一级二级| 福利在线观看一区二区| 日韩精品色呦呦| 国产精品久久久久久久久久久久久久| 操操AV电影| hd成人一区二区在线| 在线观看无码三级少妇| 久久久久97| 麻豆精品久久久久久久| 美女操逼A A| 蜜臀久久99精品久久久久久成人小说 | 人人噜夜夜操| 亚洲自拍97| 青青草乱入乱欲视频在线观看| 欧美 日韩 亚洲 春色| 色香天天| 水多多映视AV| 亚洲一区二区AV| 国内毛片四区| 国产丝袜啪啪| 97av在线观看| 中文字幕99999| 熟妇熟女一区二区三区| 天天看天天日天天操| 男女国产精品| 97精品国产精品免费观看| 99色网| 很很很很操| 夜夜骑操视频| 欧美综合777| 久草毛片| 超碰在线人人射| 久久久久久网址| 久久久久久网址| 国产精品一区二区久久精品| 人人操人人摸人人看人人干| 天天日B夜夜干B时时操B| 探花激情视频| AV天天在线观看| 大香蕉综合| 91九九九小逼| 加勒比久久av| 久久久久97| 一区不卡在线观看av| 免费一级精品啪啪视频| 色牛牛AV| 蜜臀AV成人精品蜜臀AV久久| 国产视频大全| 91人妻在线视频| 欧美的性爱网站免费| 成年女人黄网站| 人人爱操| 亚洲限制级| 综合自拍| 天操天操夜操夜月操月年年操操| www男人天堂| 四虎精品永久在线播放| 日本丝袜人妻内射| 人人扣人人操| 日韩激情视频| 美女t无毒不卡不卡| 啊啊啊想要| AV网站高清无码在线观看| 婷婷五月av| 久操操| 理论久久婷婷网8| 国产婷婷综合在线观看| 在线视频日韩欧美国产| 久9久| 男女香蕉一区二区| 国产午夜福利专区综合| 69人妻精品一区二区绯色| 欧美A√综合网| 97久操| 欧美日韩激情无码专区| 偷拍欧美激情| 蜜臀网 一区| 狠狠色狠狠色狠狠五月| 婷婷综合在线观看| 神马久久午夜| 丁香五月激情综合| 96精品一区| 欧美人与动性人交a| 婷婷色婷婷| 好舒服视频| 欧美18老人禁| 91色艳| 午夜视频久久久| 草草影院最新网址| 亚州操操穴网| 久久久久久久精| 色噜噜婷婷| 欧美综合亚洲| 精品性爱一区二区| 日美免费黄片| 青青草啪啪网| 少妇厨房愉情理伦片bd在线观看| 国产成人手机视频激情| 日本加靬比网站发布页| 欧美影院一区二区三区| 人妻天天爽夜夜爽爽| 精品免费成人久久| a级成人毛片免费视频高清| 欧美一区二区成人一卡| AA级电影三区| 歐美性天天| 亚洲乱码精品一区二区| 日本女厕偷拍| 亚洲天天做日日做天天谢日日| 日韩去日本高清在| 欧亚揄拍偷拍精品视频 | 97久久超碰国产精品| 国产高清无码一区三区二区| 欧美天天谢综合网| 国产在线观看91精品一区| 色综合中文字幕不卡| 97爱爱| 欧美亚洲激情小说| 超碰97人人cao| 五十路熟女工口 | 国产又大又粗又色生活片亚洲国产精品成人久久久综合免费 | 伊人96在线| 一,爱啪啪,在线免费视频| 午夜精品久久999热蜜桃介男人用| 人妻 欧美亚洲| 日本在线播放不卡一区| 日本2020一区二区| 加勒比在线视频| 国语av狠狠色丁香婷婷综合激情| 日本性爱不卡视频| 国产免费操逼| 久久成人午夜狠狠| 伊人久久艹| 日韩精品人妻| 九九九九免费高| 成人日本视频人妻在线| 97爱亚洲| 九九九九九九九九九五码| 91人妻素女| 久久午夜神马| 亚洲色性情三级| 97国产成人精品免费视频| 欧综合网| 欧美色日| 97香焦色区| 性爱边摸边日免费AV| 青青操日韩| 视频在线观看一二三区| 亚洲一区二区三区AV无码 | 久草这里只有精品| 大香蕉在线86| 91操人视频| 香港澳门日本三级网站| 久草色在线观看| 欧美亚洲第1页| 免费操逼视频下载| 日韩性爱小视频| 日韩有码回春沙龙第一页| 日韩女优中文字幕| 日本熟妇人妻中出视频| yaouchengrenav| 97爱爱官网| 99re99视频在线免费观看| 超碰99在线观看| 欧美日韩不卡a片| 在线日韩日本亚洲国产| 精品国产一区二区三区久久久蜜臀| 九久久精品| 五月婷婷丁香六月丁香| 麻豆久久精品亚洲精品88| 无码高清国产AV| 影音先锋少妇| 黑人精品XXX一区一二区| 亚洲AV色图一区| 丝袜熟女2P| 国产欧美美女免费观看视频| 后入日本1234| 超碰中文字幕人妻草一区| 女同在线视频一区| 中文字幕日本久久| 97超碰中文在线| 天天性射网| 日影院久久婷婷夜夜网| 久久精品72| 99热精品青草在线| 九九热精品免费视频| 大香蕉婷婷| 亚洲激情在线一区二区| 尤物一级在线免费观看| 大香网站| 性爱乱伦网址| 免费簧片在线观看| 乱伦日本色图AⅤ| 日韩欧美aⅴ综合网站发布| 欧美成人A√在线一区二区| 亚洲网站一区二区在线| 搡老女人911熟妇老熟女| 农村女一级毛卡片| 日韩精品资源专区二区| AV麻豆免费一区| 黄视频免费| 亚洲欧洲无码bt精品合集| 性爱网站一区二区| 一本大道不卡一二三区| 在线综合色| 国产97视频免费观看| 在线强奷到舒服的无码视频| 久久久久久AⅤ无码免费肉站 | 伊人久久亚洲色欲综合网站 | 成人性爱免费播放| 精品人妻中文字幕高清| 国产精品国产拍高清AV| 日本午夜福利影院| 激情小说五月天| 国产精品天美传媒| 精品一区二区麻豆| 区自美91| 夜夜躁狠狠躁日日躁av| 亚洲无码精品AV久久久| 亚洲三区视频| 久久99亚洲精品久久99果| 婷婷九月色| 日韩欧美成人大香蕉| 白丝少妇一区二区| 欧美日本视频一区| 另类图片综合| 无码WWW免费视频网站| 一区二区三区激情在线观看| 亚洲欧洲小说图片视频 | 色综合网1| 涩涩五月天| 超碰97资源大奶| 国产精品97超碰| 在线观看中文字幕| 极品尤物自安慰| 又大又白奶子| 天天操天天看| 17c嫩草51久久91嫩草| 人人操我人人干| 探花精品视频| 九九热免费在线国产视频伊人五月| 精品国产精品一区二区| 亚洲色图加勒比| 亚洲无限观看| 97超碰日韩| 国产精品久久久久久久黄无码| 国产精品盗摄 偷窥盗摄| 国产av美女被艹的乱叫| 中文字幕丝袜人妻| 67914在线兔费成人视频| 日韩欧美加勒比| 国产精品午夜高潮呻吟久久av| 色哟哟511老熟女| 97天天摸天天碰| 日韩大香蕉精品在线视频| 色汉综合| 色五月亚洲| 职场同事知名国产国产精品久久欧美日韩| 久久噜噜噜精品国产亚洲综合| 国产乱子伦一区二区三区免看| 久神马| 亚洲欧美不卡线| 一区二区三区激情在线观看| 中文字幕、久久精品国产2020、久久综合久久自在自线精品自、亚洲 | 在线观看高清AV| 4399成人黄A片| 亚洲的天堂网| 乱伦a片视频| 天天弄欧美| 天天噜| 色五月综合网| 大香蕉2017| 8050午夜少妇无码| 热热色国产一二区AV| 国产性爱在线视频一区二区| 亚欧中文字幕在线视频| www.色吧5.com| 欧美天天谢综合网| 草草电影院| AV天天综合| 国产内射爽爽大片| 色性荡荡荡荡视频| 韩国一级做a久久久久| 久久久久久久久久久六六| 四虎AV在线播放| 久热这里| 亚洲精品97| 暖暖精品二区三区观看| 日产操逼| 成人老鸭窝人人在线视频| 国产毛片片精品天天看视频| 嗯……啊…嗯嗯…啊…好舒服| 亚洲综合九| 午夜一区二区三区国产| 中文字幕视频免费| 国产精品香蕉热久久新品| 本道在线| 五月天婷婷成人网| 91成人18| 精品97精品97| 欧美强奸乱| 四虎免费在线播放| 98一区二区精品| 国产欧美在线观看免费观看| 久久色一区二区| 欧美人妻一区| 精品欧美乱码久| 国产日韩精品一区二区三区| 久久性爱精品一区| 吊色| 久久天堂婷婷网| 精品日韩人妻精品一二三区| 二三四区精品| 丁香五月AV| 性爱视频免费网址| 日韩精品系列| 精品四五区| 成人av影院在线观看| 一级免费精品| 国产夜夜艹| 亚洲色图日韩精品| 97综合国产| 欧美少妇性乱| 狠狠操综合| 狠狠色噜噜狠狠狠狠2018| 天天综合网~91综合网| 啊啊啊啊嗯嗯嗯用力好爽 | 五月激情天| 人妻献身系列第54部| 日韩无码服务区| 婷婷国产精品九区| 懂色AV蜜臀无码精品APP | 蜜臀AV秘一区翔田千里| 亚洲欧洲激情| 日韩精品三区四区| 国产一区二区啪啪视频| 内射小黄片| 久久久久久无码人妻中文字幕| 免费精品人妻一区二区三| 人人澡人人澡人人| 懂色AV中文| 志村玲子视频一区二区| 人人摸人人添人人操 | 成人蜜乳小视频网站| 欧美最大综合网| 91嫩草欧美| 五月综合视频| 色嗨嗨在线| 综合亚洲欧美精品日韩?v| 欧美色图另类图片| 亚洲欧美在线综合| 在线综合 亚洲 欧美中文字幕| 操逼视频国产无套| 九热中文字幕| 亚洲欧洲日韩中文字幕一区| 亚洲自拍欧美色综合| 成年男人的天堂| 五月天婷婷综合| 亚洲码专区| 秋霞久久亚洲精品成人| 色黄污美女啪啪啪免费网站| 精品一区二区三区免费古装毛片香港三级日本三级人妇 | 操B久久| 五月丁香六月婷| 亚洲乱熟女一区二区三区大香蕉| 啊啊啊啊好爽好舒服一区二区易域| 91亚洲不卡一区| 69超碰综合| 91国产精品在线看| 天天爽天天爽| 99热这里只有精品99| 久久性视频| www色色com| 六十路日本| 婷婷操逼| 蜜臀久久99精品久久久老,,| 99爱在线视频| 能看的av| 精品夜夜澡人妻无码| 丁香六月婷| 成人日韩欧美| 人妻嗯啊啊在线播放| 天堂精品在线| 久久9亚洲| oumeisetupian| 99国产精品免费| 天天综合网1| 综合色拍| 亚州五月| 亚洲加勒比久久日本道| 日韩肏逼视频| AA级电影三区| 九色在线熟女国产黑人| 自拍大香蕉乱插| 色婷婷香蕉| 992这里有精品| 亚洲欧美爆| 60秒免费小视频| 91在线国产后入风骚翘臀美女素人| 亚洲情色91| 操学生天天| 99久久com免费视频′| 2017天天操天天日| 97超碰超| 秋霞怕怕片| 97在线精品观看视频| 丝袜美腿制服人妻二区中文字幕| 久久二| 国产午夜精品理论片一二三区区| 97久久超碰国产精品| 91丝袜视频在线观看| 少妇一级无码精品| 久久亚洲AV无码专区首页| www网站黄| 天美av在线观看| 青青草字幕AV| 亚洲性综合11| 台湾一区国产高清在线| 嫩草影院在线观看精品 | 九月激情婷婷| 亚洲精品日韩国产欧美| 日本有码影片下载| 色www精品视频在线观看| 一卡二卡三卡| 日韩熟女乱伦中出| 99久久婷婷国产综合| 国产性感在线观看| 极品人妻少妇综合| 国产精品日韩在线一区| 国产亚洲在线观看| 欧美在线视频播放| 一区二区三区在线资源| 亚洲骚逼少妇| 亚洲高清无码在线桃色| 乱欲性色| 国产路线专区| 性色生活片久久毛片婬片免费放女人一级毛片 | 日欧毛片久久| 友优传媒精品在线一区二区| 亚洲伊人a线观看视频| 国产在线视视频有精品| 精品国产99| 欧美性夜| 十八禁视频网站| 欧美色图下一页| 亚洲欧美人妻| 国产免费永久精品无码| 欧美国产成人在线| 欧美精品成人一区二区在线观看 | 欧美姓爱综合网| 又大又长又粗又爽又黄| 色av中文字| 国产农村妇女毛片精品久久| 爱妃国产亚洲视频中文字幕| 99色热| 午夜精品久久久99热蜜桃的功能特点| 91N综合网在线| 中文字幕在线免费观看2| 91精品大奶人妻| 欧美一区二区三区成人性生活| …中文字幕亚洲乱,97人妻无码费视…| 天堂网 主播 亚洲| 日本乱人伦片中文三区| 天堂蜜桃无码视频一区二区| 欧美综合色图片| 大伊香蕉在线视频免费| 国产精品亚洲日韩骚欢乐谷最新地址发布页huanieguty性屋娱乐妖精视频 | 婷婷在线视频在线观看| 亚洲色鬼| 淫荡网址| 久操B网| 久操97| 黄页大片在线观看| 好涩综合| 欧美有码激情视频一区二区三区| 精品国产99| 影音先锋每日最新资源在线观看 | 97舔舔| 亚洲天天更新| 天天91~综合入口| 亚洲综合首页| 热天堂一区二区| 亚洲无码电影久久久| 97玖玖人妻| 最新av网站在线观看| 东北女人| 国产精品婬乱一级毛片彝族| 黑人粗大V S日韩女优视频| 一级黄色性爱A级片| 三级片大波波| 97精品97久久| 精品一二三区久久AAA片| 亚洲少妇自拍中文字幕懂色| av一区二区三区 中文| 欧美性夜| 亚洲欧洲美腿丝袜| 中文字幕一区二区三区四区在线视频| hd成人一区二区在线| 人妻无码视频一区二区三区久久| 久久精品一区二区三区四区五区| 日韩欧美国产高清视频| 欧美激情亚洲| 青青操97| 小视频国产| 大干人妻| 天天综合网一91网| 人妻献身系列第54部| 小草av不卡亚洲二区 | 天天欧美色| 综合激情二| 涩亚洲欧洲| oumeisetu综合| 人人看人人插| 久啪视频| 国产久久视频| 国产一区二区三区影片| 国产一区在线播放| 少妇精品久久久| 久久99视频| 成人无码在线超碰网| 无卡一区=区| 91色综| av天堂精品久久| 日韩久射综合| 性生活无遮挡纯毛片在线看| 国产67194| 岛国激情视频在线观看| 97神马久久| 亚洲色香| 国产欧美第五页| 嫩草影院在线观看精品 | 国产成年女黄特黄| 国产精品3| 九九热超碰97亚洲最新香蕉| 韩国一级婬片A片AAAAA| 日韩人妻一区二区| yazhououmeizongya| 青青操在线亚洲视频观看欧美在线 | 欧美后入式| 二区熟妇韩日| 91丨九色丨国产打屁股| 欧美色视频在线| 欧美色网| 漂亮人妻被强中文字幕hd| 天美传媒Av在线| 久都青青视频| 六月婷婷五月丁香| 中国乱伦一区二区| 人人操 欧美| 超碰色老头| 亚州欧美在线| 9ⅰ久久久天天| laoshunv91| 国产老熟女| 日韩三四五区| 天天日天天插| 十八禁啪啦拍视频无遮挡| 黄在线| 亚洲日本激情| 男女日B国产| 搡老女人老91妇女老熟女| 少妇三p| 蜜臀一二三区| 97干综合网| 色综合久久夜色精品国产天堂| 911粉嫩人妻| 亚洲日韩美女中文字幕乱| 成人无码在线超碰网| 青娱乐福利99| 日韩有码 一区二区三区| 中文字幕三四区| 欧美日韩在线小说| 大香蕉中文在线| 大茄子熟女AV导航| 久久久亚洲精品中文字幕人妻| 三级片大波波| 九九热免费国产视频婷婷伊人| 蜜桃丰满熟妇av无码区不卡| 日韩去日本高清在| 亚洲国产欧美中日韩成人综合视频| 床戏久久久av一区二区麻豆| 欧美手机在线综合| 久热这里| 人人操人人肉久久精品| 九九热三级片| 久久97| 亚洲AV成人无码一二三久久| 亚洲精品一区二区精品| 国模私拍一区二区三区神乳| 人人贴人人摸| 亚洲成熟国产精品美女| 强免费黄色网址| 五月婷在线| 啊啊啊啊啊啊啊国| 超碰在线974| 婷婷香网站| 欧美在线第五页| 久久啊啊| 国产在线观看91精品一区| 天天摸夜夜添无码小视频| 人人干人人搞人人摸| 强奸a片网| 91N欧美| 久操在97| 九九九九九九综合| 粉嫩av在线| 亚洲国产一区二区入口| 婷婷丁香熟妇综合网| 91无人区卡一卡二卡三乱码入口最新版:能让用户有更多选择的选择-经典说说-爱 | 中国大陆国产高清AⅤ毛片| 精品一区二区人妖| 69超碰综合| 熟女一区二区三区| 中文字幕激情小说| 波多野42部激情无码喷潮| 国产乱码精品一区二区三区四川| 成人性爱免费播放| 亚洲无码一二三区| 99这里有精品| 99热导航| 日本二三四区| 国产精品白丝在线播放| 国产精品无码AV网站| 亚洲美乱| 国产欧美日产一区二区三区 - 国产欧美日 | 国产少妇内射| 青娱乐国产剧情av一区| 午夜影美女日鸡鸡天天视频国产| 中文字幕精品一区欧美| 91热爆在线| 爱爱动态试试看6 0秒| 熟妇人妻一二三区免费| 色呦呦国产精品免费看| 日韩中文字幕二区| 亚洲男人的天堂一区二区| 国模91| 久久久99免费| 偷拍伦理视频| 精品欧美日韩在线观看| 亚洲成人精品在线一区| 免费看日本操逼视频| 天天看高清麻豆| 国产高清自拍| 99热99在线| 日韩欧美天天爽爽爽天天爽爽| 91N综合网在线| 午夜精品久久久| 91|九色|国产熟女| 综合97亚洲| 免费看黄片现成| 久7色| 最近2019中文字幕国语免费版| 在线观看av区| 色娱乐色呦呦夜夜夜夜av| 日韩肏逼视频| 亚洲人妻AV| 亚洲综合色在线| 亚洲欧美综合区自拍另类 | 羞答答AV中文字| 色就色综合| 97超碰天天爱天天爱| 日韩人妻丝袜中文字幕| 久久老子无码午夜伦不卡| 小骚逼被操的爽不爽| 亚洲欧洲自拍图片专区满春格| 亚洲成人福利电影免费| 97中文字幕色| 日本乱人伦片中文三区| 九九无码久久精品视频| 91欧美网| 日日干夜夜干| 亚洲 欧美 第一页 | 99久久久er直播网址| 久久精品免视看国产成人﹣蜜臀av一区. 久久精品免视看国产成人,蜜臀av一区 | 久草精品国产蜜臀| AV乱伦国产| 中文一区二区婷婷视频| 天天综合网网欲色| 日韩啪啪啪啪啪| 天天干电影| 色综合中文字幕不卡| 无码高清操逼| 啊啊啊啊啊在线视频| A片A5445444| 日本不卡二三区| 性爱免费视频成人| 青草园大香蕉| 国产女人成人精品视频| 国产日韩怡红院| 日韩AV一区二区三区四四| 偷拍 亚洲 欧美| 啊啊啊啊视频免费| 亚洲激情在线观看一区| 天天综合网AV91| 国产一区二区欧美日本| 农村少妇久久久久久久| 啊啊啊啊一区| 超碰97人人cao| 日本久久综合| 极品色www影院| 久久啊啊啊| 啊啊啊啊在线观看网址| 久操网视频| 婷婷五月天色网| 99这里有精品| 亚洲另类欧美精品| 性色av一区二区| 全球成人中文在线| 欧美在线啊啊| 天天天天天天天天综合| 视频分类 国内精品| 欧美美女视频| 北京美女一区二区| 久久久成人国产精品无码| 69精品| 亚洲和欧美裸体美女双飞视频| 国产精品九九九| 一区二区国产视频在线观看| 亚洲色诱惑| 亚洲日韩在线a不卡99精品| 91性| 亚州情色j区| 超碰在线观看av不卡| 久久伊人影院| 久日91在线| 亚洲黑丝在线| 插穴性爱视频在线观看| 91高潮| 亚洲情色综合网| 插入综合网| 亚洲色图殴美色图激情乱伦| 婷婷丁香激情| 男女香蕉一区二区| 精品久久99| 性爱av网站| 国产最火爆久久国产网站网站| 久热伊人99re| 成人福利视频网| 亚洲欧美国产中文视频| 综合网亚洲在线| 天天内射| 婷婷五月天_亚洲小说欧美激情另类_精品久久国产字幕 | 成人无码欧美一级A片狼牙直播| 日本日皮视频逼| 日B操| 久久区| 草B在线| AV色五月天| 诱惑人妻欧美一区在线播放| 欧美日韩成人| av天堂手机版追回| 免费的黄片有限公司| 欧美色亚洲| 超碰色图| 国内一区二区三区| 亚洲自拍一区夜夜操| 暖暖精品二区三区观看| 色5月婷婷| 亚洲日韩美女中文字幕乱| 国产91av在线播放| 97在线免费视频| 亚洲狠| 亚洲av资源| 色网亚洲人| 无码精品啪啪啪一区二区三区三州| 久久久久国产无av| 日本高清_区二区三区| 亚洲伊人a线观看视频| 激情综合网激情综合| 啊啊啊免费| 偷拍视频青青草在线视频| 97亚洲自在精品在线观看| 97jingpin| 91亚洲欧美综合高清在线| 亚洲黄色网址| 97在线无精品| 日韩一级二级三级免费看完整版国语版| 国产精点久久久成人| 精品一区二区在线针对华人免费观看这里只有精品免费观看 | 亚洲国产91精品一区二区久久| 亚洲第一精品在线视频 | 屁股久久久久久久久| 宗合情欲网| 久久熟妇五十路一区| 欧美少妇第一页| 97爱爱影院| 伊人伊人LD| 97se综合| 欧美桃色网| 东京太热男人的天堂久久久| 欧美一级二级三级| 亚洲天天操| 欧美高清18A片| 在线播放免费av福利片| 在线观看无码三级少妇| 韩国一级AAA| a级理论午夜日本|