การต่อยอดแบ็กเอนด์ของคุณ
คุณได้สร้างแบ็กเอนด์แบบ standalone จากไซต์หนึ่งแล้ว มันเป็น repository ปกติ และ ไม่ import สิ่งใดจาก CMS ในขณะ runtime เอกสารนี้บอกว่าโค้ดของคุณควรอยู่ที่ใด การสร้างใหม่ (regeneration) เขียนทับอะไร และปฏิเสธอะไร
คำตอบสั้น ๆ: src/owned/ เป็นของคุณตลอดไป apps/site/src/owned/ และ
apps/site/src/pages/owned/ เป็นของคุณในไซต์ที่ถูกส่งออก package.json,
wrangler.jsonc, .nvmrc, .gitignore, README.md และ workflow ของคุณเอง
เป็นของคุณที่จะเก็บไว้ ทุกอย่างที่เหลือจะถูกเขียนใหม่จากนิยามโมเดลในทุกครั้งที่
สร้างใหม่
ที่มาของกฎนี้: backend/src/lib/graduate/zones.ts ตารางด้านล่างถูก
ตรวจสอบเทียบกับโค้ดนั้นโดย backend/test/extending-your-backend-doc.test.ts
ดังนั้นเอกสารนี้จึงไม่สามารถคลาดเคลื่อนไปจาก emitter ได้
สิ่งที่คุณเป็นเจ้าของ และสิ่งที่การสร้างใหม่เขียนทับ
หัวข้อที่มีชื่อว่า “สิ่งที่คุณเป็นเจ้าของ และสิ่งที่การสร้างใหม่เขียนทับ”แบ็กเอนด์ที่สร้างขึ้นมีไฟล์สามประเภท กฎจะตัดสินโซนจาก PATH เพียงอย่างเดียว — ไม่ใช่จาก comment ที่เป็นเครื่องหมาย และไม่ใช่จากรายการที่ใครสักคนดูแล
| โซน | ใครเป็นเจ้าของ | การสร้างใหม่ทำอะไร |
|---|---|---|
generated |
emitter | เขียนใหม่ทุกครั้งที่รัน |
owned |
นักพัฒนา | เขียนครั้งเดียวเป็น scaffold และไม่แตะอีกเลย |
shared |
ทั้งสองฝ่าย | เขียนเมื่อยังไม่มีไฟล์ และไม่เขียนทับเด็ดขาด |
มีข้อยกเว้นหนึ่งข้อ ซึ่งกำหนดตาม key: package.json — ทั้งไฟล์ที่ root และไฟล์ใน
apps/site/ — จะถูก MERGE ไม่ใช่ปล่อยไว้เฉย ๆ ดู “การ merge manifest”
กฎที่แน่นอนเป็นดังนี้ คำถามเกี่ยวกับไซต์จะถูกถามก่อน (FIRST) เพราะ
apps/site/package.json ใช้ชื่อแบบ shared ที่ API ก็ใช้เช่นกัน และ
apps/site/src/owned/x ไม่ได้ขึ้นต้นด้วย src/owned/:
- path ที่ขึ้นต้นด้วย
apps/site/src/owned/หรือapps/site/src/pages/owned/เป็น owned - path ที่เป็น
apps/site/package.json,apps/site/package-lock.json,apps/site/.npmrcหรือapps/site/wrangler.jsoncเป็น shared - สิ่งอื่นใดภายใต้
apps/site/เป็น generated - path ที่ขึ้นต้นด้วย
src/owned/เป็น owned - path ที่เป็น
.github/workflows/dee-wan-build.ymlหรือ.github/workflows/deploy-from-repository.ymlเป็น generated ทั้งสองเป็น การกำหนดค่าของเครื่อง การแก้ไขไฟล์เหล่านี้ต้องไปถึงโปรเจกต์ที่ถูกรับไปดูแลแล้ว - path ที่เป็น
package.json,package-lock.json,.npmrc,.nvmrc,wrangler.jsonc,.gitignore,README.mdหรือที่ขึ้นต้นด้วย.github/เป็น shared - ทุกอย่างที่เหลือเป็น generated
มีสอง path ที่ไม่ถูกสแกนเลย ดังนั้นจึงไม่ถูกทำ fingerprint และไม่ถูก
stage เด็ดขาด: src/serve.local.mjs และ src/credential-digest.mjs ทั้งสองเป็นผลลัพธ์ของ BUILD
(BUILD OUTPUT) ที่อยู่ใน src/ เพราะช่วยให้ Prisma client ที่สร้างขึ้นอยู่ภายนอก bundle
ทั้งสองอยู่ใน .gitignore — การเสนอไฟล์เหล่านี้ให้ git add เคยทำให้การ push ทั้งหมดล้มเหลว
ไฟล์ generated ที่ถูกแก้ไขจะถูกปฏิเสธโดยระบุชื่อ (REFUSED BY NAME) ในการสร้างใหม่ครั้งถัดไป พร้อมบอกที่ ที่ควรย้ายงานไป มันจะไม่ถูกเขียนทับแบบเงียบ ๆ เด็ดขาด ดู “สิ่งที่ถูกปฏิเสธ”
โซนของแต่ละ path ที่ถูกส่งออก
หัวข้อที่มีชื่อว่า “โซนของแต่ละ path ที่ถูกส่งออก”| Path | โซน |
|---|---|
prisma/schema.prisma |
generated |
graduation.manifest.json |
generated |
src/app.ts |
generated |
src/worker.ts |
generated |
src/security.ts |
generated |
src/owned/routes.ts |
owned |
src/serve-cli.ts |
generated |
migrations/0002_graduation_ledger.sql |
generated |
scripts/regenerate.mjs |
generated |
scripts/emit-migration.mjs |
generated |
scripts/file-manifest.mjs |
generated |
scripts/portable-client.mjs |
generated |
scripts/configure-deployment.mjs |
generated |
tsconfig.json |
generated |
wrangler.example.jsonc |
generated |
wrangler.build.jsonc |
generated |
scripts/load-snapshot.mjs |
generated |
data/published-snapshot.json |
generated |
.github/workflows/dee-wan-build.yml |
generated |
.github/workflows/deploy-from-repository.yml |
generated |
.github/workflows/anything-else.yml |
shared |
package.json |
shared |
package-lock.json |
shared |
.npmrc |
shared |
.nvmrc |
shared |
wrangler.jsonc |
shared |
.gitignore |
shared |
README.md |
shared |
apps/site/src/owned/config.mjs |
owned |
apps/site/src/pages/owned/thanks.astro |
owned |
apps/site/package.json |
shared |
apps/site/package-lock.json |
shared |
apps/site/.npmrc |
shared |
apps/site/wrangler.jsonc |
shared |
apps/site/src/lib/pages.json |
generated |
เพิ่ม route ของคุณเอง
หัวข้อที่มีชื่อว่า “เพิ่ม route ของคุณเอง”src/owned/routes.ts เป็น scaffold ที่เขียนครั้งเดียว และถูกส่งมาแบบว่างเปล่า (EMPTY) โดยตั้งใจ
ใส่ route ของคุณไว้ที่นั่น:
export function ownedRoutes(prisma: GuardedPrisma) { const routes = new Hono()
routes.post('/checkout', async (c) => { const body = await c.req.json() return c.json({ ok: true }) })
return routes}src/app.ts mount มันด้วย app.route('/api', ownedRoutes(deps.prisma)) เป็นลำดับสุดท้าย (LAST) —
หลังจาก router ของทุกโมเดล ดังนั้น path ที่คุณเลือกจะไม่มีทางบัง path ที่สร้างขึ้นได้
/checkout ของคุณข้างต้นจะให้บริการที่ /api/checkout
สิ่งที่คุณได้รับสืบทอดมา: การยืนยันตัวตนทำงานบน app.use('*') ก่อนที่จะมีสิ่งใดถูก
mount ดังนั้นทุก request ที่มาถึงคุณได้ถูกระบุตัวตนหรือถูกปฏิเสธไปแล้ว
ภายใน handler คุณมี c.get('principal'), c.get('accessVariant') และ
c.get('prisma') client ที่มี guard ถูกส่งเข้ามา (PASSED IN) แทนที่จะถูก import ดังนั้น
query ของคุณจะทำงานภายใต้ extension เดียวกับที่ router ที่สร้างขึ้นใช้
สิ่งที่คุณต้องไม่สันนิษฐาน — การตรวจสอบสิทธิ์จะถามว่า request นั้นเป็นของ MODEL ใด
และตอบโดยใช้ PREFIX /api/<model>…:
- path ที่ขึ้นต้นด้วยชื่อของโมเดลจะถูกตรวจสอบสิทธิ์โดยถือว่าเป็นโมเดลนั้น (AS THAT MODEL)
/api/articles-reportตรงกับโมเดลarticleดังนั้นผู้เรียกต้องมีสิทธิ์ของ article จึงจะเข้าถึงได้ — มากหรือน้อยกว่าที่คุณตั้งใจไว้ - path ที่ไม่ตรงกับโมเดลใดจะ resolve ไปยังไม่มีโมเดล ผู้เรียกที่ใช้ session จะถูก
ควบคุมโดย operation เพียงอย่างเดียว (GET, POST…) ส่วนผู้เรียกที่ใช้ read token จะถูกปฏิเสธ
เว้นแต่ scope ของมันคือ
*
ดังนั้นให้เลือก segment แรกที่ไม่มี slug ของโมเดลใดใช้ได้ — /checkout,
/webhooks/stripe, /reports/daily หาก route ต้องการกฎของตัวเอง ให้บังคับใช้
ใน handler ไม่มีสิ่งใดในนั้นถูกตรวจสอบให้คุณ
สำหรับ route ของไซต์แทนที่จะเป็น route ของ API ให้เพิ่มไฟล์ภายใต้
apps/site/src/pages/owned/ route ของ Astro มีอยู่ได้ด้วยการเป็นไฟล์ภายใต้
src/pages ดังนั้นหน้าที่เป็น owned จึงอยู่ใน apps/site/src/owned/ ไม่ได้ หน้านั้นจะให้บริการ
ภายใต้ /owned/… และ address resolver จะปฏิเสธหน้าที่สร้างขึ้น, chrome
route หรือ redirect ใด ๆ ที่จะบังพื้นที่ URL นั้น
เพิ่ม business logic
หัวข้อที่มีชื่อว่า “เพิ่ม business logic”ที่เดียวกัน จะเป็นไฟล์ใดก็ได้: ทั้ง tree ของ src/owned/ เป็นของคุณ เพิ่ม
src/owned/pricing.ts แล้ว import จาก src/owned/routes.ts ใส่สิ่งเหล่านี้ไว้ที่นั่น:
- route ของคุณเอง,
- business logic,
- การยืนยันตัวตนเพิ่มเติมนอกเหนือจากการตรวจสอบ bearer ที่ถูกส่งออก,
- การเชื่อมต่อกับระบบของบุคคลที่สาม,
- ตารางของคุณเองและ migration ของตาราง,
- ทุกสิ่งที่ต้องอยู่รอดผ่านการสร้างใหม่
ไฟล์ owned ไม่ถูกทำ fingerprint เด็ดขาด — นั่นแหละคือ (IS) คำสัญญา อย่าใส่โค้ดของคุณ ไว้ในไฟล์ generated “แค่ชั่วคราว”: การสร้างใหม่ครั้งถัดไปจะปฏิเสธการรันทั้งหมดโดยระบุ ชื่อไฟล์นั้น
ในไซต์ จุดต่อขยายที่มี type อยู่ใน apps/site/src/owned/:
Head.astro, BodyEnd.astro, slot ของ layout, section
Wrapper/overrides และ config.mjs สำหรับ Astro integration และ origin ของ site
เพิ่ม dependency
หัวข้อที่มีชื่อว่า “เพิ่ม dependency”แก้ไข package.json และติดตั้งผ่านตัวติดตั้งที่ผ่านการตรวจสอบ:
node scripts/install-dependencies.mjsรายการของคุณจะถูกเก็บไว้ — ดู “การ merge manifest” npm ci และ npm install ไม่ใช่
เส้นทางการติดตั้ง: ตัวติดตั้งจะตรวจสอบ npm เทียบกับ .nvmrc และ packageManager,
แตกไฟล์โดยปิด script, audit tree เทียบกับ allowScripts ที่แน่นอน จากนั้น
รัน npm rebuild สำหรับ script ที่อนุมัติแล้วเท่านั้น
dependency ของไซต์ใส่ไว้ใน apps/site/package.json และติดตั้งด้วย
node scripts/install-dependencies.mjs apps/site island ของ Svelte หรือ React ยัง
ต้องเพิ่ม integration ที่ปักหมุดเวอร์ชันไว้ลงใน apps/site/src/owned/config.mjs ด้วย
เพิ่ม binding
หัวข้อที่มีชื่อว่า “เพิ่ม binding”แก้ไข wrangler.jsonc ไฟล์นี้เป็น shared: เขียนเมื่อยังไม่มี และไม่เขียนทับเด็ดขาด ดังนั้น
binding ของคุณจะคงอยู่ wrangler.example.jsonc ที่อยู่ข้างกันเป็น GENERATED — เป็น template
ที่ไม่มี account id, ไม่มี route และไม่มี database id เพราะ generator นี้ไม่ได้
ตัดสินใจว่าคุณจะ deploy ที่ใด ให้คัดลอกจากไฟล์นั้น อย่าแก้ไขมัน
wrangler.build.jsonc ก็เป็นไฟล์ generated เช่นกัน และเป็นสิ่งที่ npm run build ใช้ bundle
wrangler.deploy.jsonc ถูกเขียนโดย deployment
(npm run deploy:configure) และอยู่ใน gitignore
binding ของไซต์ใส่ไว้ใน apps/site/wrangler.jsonc ซึ่งเป็น shared ภายใต้เงื่อนไขเดียวกัน
เพิ่ม CI ของคุณเอง
หัวข้อที่มีชื่อว่า “เพิ่ม CI ของคุณเอง”เพิ่ม workflow ภายใต้ .github/workflows/ โดยใช้ชื่อใดก็ได้ยกเว้น
dee-wan-build.yml และ deploy-from-repository.yml .github/ เป็น prefix แบบ shared
ดังนั้นไฟล์ของคุณจะถูกเขียนโดยคุณและไม่ถูกแตะต้องเลย สองชื่อนั้นเป็น
generated: เป็นการกำหนดค่าของเครื่อง และการแก้ไขไฟล์เหล่านี้ต้องไปถึงโปรเจกต์ของคุณ
ในการสร้างใหม่ครั้งถัดไป
สิ่งที่การสร้างใหม่เปลี่ยนแปลง
หัวข้อที่มีชื่อว่า “สิ่งที่การสร้างใหม่เปลี่ยนแปลง”การสร้างใหม่เขียนทุก path ที่เป็น generated ใหม่จากนิยามโมเดลปัจจุบัน:
schema, route, worker entry, build script, workflow ที่ถูกส่งออก, ไซต์ที่ถูกส่งออก มัน
เพิ่ม migration ต่อท้ายสำหรับการเปลี่ยน schema — ไม่เขียน migration ในอดีตใหม่เด็ดขาด
มันไม่แตะต้อง (NOT):
- สิ่งใดภายใต้
src/owned/,apps/site/src/owned/หรือapps/site/src/pages/owned/, - ไฟล์ shared ที่มีอยู่แล้ว (
wrangler.jsoncยังคง binding ของคุณไว้), - migration ที่ถูก apply แล้ว,
- ประวัติ git ของคุณ
package.json เป็นไฟล์ shared ไฟล์เดียวที่มันเปลี่ยนแปลง (DOES change) และเปลี่ยนด้วยการเพิ่ม (ADDING) เท่านั้น ดู
“การ merge manifest”
ตัวเลือก guard ของ route ที่สร้างขึ้นมาจาก Settings → Source & delivery → Generated API guards การสร้างใหม่จะเขียนค่าเหล่านี้ลงใน route config ที่สร้างขึ้น ตัวเลือกที่ไม่ได้ตั้งค่าจะใช้ค่าเริ่มต้นของ package

sidecar .dee-wan-files.json เก็บ fingerprint ของไฟล์ generated ทุกไฟล์ตามที่
emitter เขียนไว้ครั้งล่าสุด นั่นคือวิธีตรวจจับว่า “คุณแก้ไขไฟล์นี้” ไฟล์ owned
ไม่ถูกทำ fingerprint เด็ดขาด — นั่นแหละคือ (IS) คำสัญญา
การสร้างใหม่ทำงานได้โดยไม่ต้องมี CMS generator ถูกคอมไพล์ไว้ใน repository ของคุณ
ตอน graduation (scripts/dee-wan-generator.mjs), ปักหมุดด้วย digest ใน
graduation.generator.json และทุก script ที่ถูกส่งออกจะตรวจสอบหมุดนั้นก่อนที่จะ
import มัน npm run regenerate ต่อ schema, app, Prisma client
และการเขียนใหม่เพื่อการย้ายระบบ (portability) เข้าด้วยกันตามลำดับนั้น
สิ่งที่ถูกปฏิเสธ และวิธีย้ายงาน
หัวข้อที่มีชื่อว่า “สิ่งที่ถูกปฏิเสธ และวิธีย้ายงาน”ไฟล์ generated ที่ถูกแก้ไขจะไม่ถูกเขียนทับ และไม่ถูกรับเป็นของคุณ การรันจะหยุดและ ระบุชื่อไฟล์:
- ไฟล์ generated ที่ไบต์เปลี่ยนไป —
“
<path>is generated and has been edited. Move your change undersrc/owned/, then delete this file so it can be regenerated.” - ไฟล์ที่ path แบบ generated ซึ่ง manifest ก่อนหน้าไม่เคยบันทึกไว้ —
“
<path>is not in the previous manifest. If it is yours, move it undersrc/owned/and delete it from here.”
การย้ายงาน: คัดลอกการเปลี่ยนแปลงไปยังไฟล์ใหม่ภายใต้ src/owned/, import มัน
จาก src/owned/routes.ts, ลบไฟล์ที่ถูกแก้ไข แล้วสร้างใหม่ emitter
จะเขียนไฟล์ที่ถูกลบขึ้นใหม่จากนิยาม
ไฟล์ที่ emitter นำออกจะถูกลบก็ต่อเมื่อเป็นของเรา และ (AND) ไม่ถูกแก้ไขเท่านั้น สิ่งอื่นใดจะถูกปล่อยไว้ที่เดิม
แถวของเนื้อหาทำตามสัญญาเดียวกันในระดับที่ลึกลงไปอีกขั้น: ตารางเนื้อหาที่สร้างขึ้น
เป็นของการรัน และแถวที่ถูกเขียนลงในตารางนั้นจะทำให้การรันครั้งถัดไปปฏิเสธด้วย
observed_row_set_mismatch ตารางของคุณเองและแถวของคุณเองจะอยู่รอด — นั่นคือ
จุดประสงค์ของ src/owned/ และ migration ของคุณเอง
snapshot ที่เผยแพร่แล้ว data/published-snapshot.json เป็น GENERATED หากแก้ไข
การสร้างใหม่ครั้งถัดไปจะปฏิเสธมันโดยระบุชื่อ ตัว loader ก็ปฏิเสธเช่นกัน: ไซต์ผิด,
artifact ผิด, ไบต์เปลี่ยน, การโหลดบางส่วน, การเล่นซ้ำที่ขัดแย้งกัน การโหลดไบต์เดียวกัน
สองครั้งปลอดภัยและไม่เขียนสิ่งใด
หลังการแยกตัว (detach) จะไม่มีสิ่งใดสร้างสิ่งใดใหม่อีก ดังนั้นทุกไฟล์ — รวมถึงไฟล์ generated — เป็นของคุณที่จะแก้ไขได้ ก่อนการแยกตัว ไฟล์ generated ที่ถูกแก้ไขจะถูก ปฏิเสธโดยระบุ path ที่แน่นอนของมัน
การ merge manifest
หัวข้อที่มีชื่อว่า “การ merge manifest”ไฟล์ package.json ทั้งสองไฟล์ — ที่ root และ apps/site/ — เป็น shared แต่ถูก MERGE กฎ
“ไม่เขียนทับเด็ดขาด” แบบบริสุทธิ์ยังหมายถึง “ไม่เพิ่มเด็ดขาด” ด้วย ดังนั้นในวันที่ emitter เริ่มเขียน
โค้ดที่ import package ใหม่ โปรเจกต์ที่ถูกรับไปดูแลแล้วจะสร้างใหม่ออกมาเป็น
ซอร์สที่ npm ci resolve ไม่ได้ ความล้มเหลวจะปรากฏขึ้นอีกสองขั้นตอนถัดไปในรูปของ
tsc --noEmit หรือ astro check ที่ระบุชื่อโมดูล ไม่ได้ระบุชื่อ
dependency ที่ขาดไป
กฎการ merge ซึ่งเหมือนกันสำหรับทั้งสองไฟล์:
- block ที่ถูก merge:
dependencies,devDependencies,overrides; - key ที่ไฟล์ของคุณมีอยู่แล้ว: เป็นของคุณ (YOURS) ค่าไม่ถูกแตะต้อง รวมถึงเวอร์ชันที่คุณ จงใจเปลี่ยนออกจากเวอร์ชันที่ปักหมุดไว้;
- key ที่มีเฉพาะใน template: ถูกเพิ่ม (ADDED);
- ไม่มีสิ่งใดถูกลบออกเลย;
packageManagerถูกเพิ่มเมื่อยังไม่มี และเป็นของคุณเมื่อมีอยู่แล้ว;- รายการ
allowScriptsถูกเพิ่มเฉพาะในกรณีที่คุณยังไม่ได้ตัดสินใจเกี่ยวกับ package และเวอร์ชันนั้น — ค่าtrueและfalseของคุณยังคงอยู่; - การสร้างใหม่ที่เหมือนกันครั้งที่สองเปลี่ยนแปลงศูนย์ไบต์
package.json ที่ parse ไม่ได้จะถูกปล่อยไว้โดยไม่แตะต้อง การเขียนทับคือทิศทาง
ที่ทำลายข้อมูล และ build จะปฏิเสธแทนคุณไม่ว่าในกรณีใด
lockfile ทำตาม manifest เมื่อการ merge เพิ่มรายการ
package-lock.json ที่ติดมาจะไม่ได้อธิบาย manifest อีกต่อไป ดังนั้น emitter จะรีเฟรชมัน
ด้วย npm install --package-lock-only ก่อนติดตั้ง lockfile และ
manifest จึงไม่สามารถขัดแย้งกันได้ สิ่งนี้ได้รับการพิสูจน์โดย backend/test/graduate-site-build.test.ts
(ต้องเปิดใช้เอง, DEEWAN_SITE_BUILD=1): site manifest ที่ถูกรับไปดูแลแล้วจากก่อนที่จะมี
block devDependencies สามารถติดตั้ง, typecheck และ build ได้หลังการสร้างใหม่
ประตูหน้าสองบาน เส้นทาง deployment เดียว (ONE)
หัวข้อที่มีชื่อว่า “ประตูหน้าสองบาน เส้นทาง deployment เดียว (ONE)”| ประตูหน้า | Workflow | อ่าน CMS หรือไม่? | สร้างใหม่หรือไม่? | deploy เองหรือไม่? |
|---|---|---|---|---|
| managed | dee-wan-build.yml |
ใช่ — DEE_WAN_URL, build token, เวอร์ชันของโมเดล |
ใช่ แล้ว commit | ไม่ (NO) — มันเรียกอีกตัวหนึ่ง |
| repository-only | deploy-from-repository.yml |
ไม่ (NO) | ไม่ | ใช่ |
workflow แบบ managed มีสาม job: build ดึงนิยาม, สร้างใหม่,
ตรวจสอบความถูกต้อง และ commit; deploy เรียก deploy-from-repository.yml
(workflow_call) สำหรับ commit นั้นพอดีและรอ; report แจ้ง
ผลลัพธ์ให้ Dee Wan ภายใต้ build attempt ที่เริ่มมัน มันไม่มีขั้นตอน migrate, ไม่มี
wrangler deploy และไม่มี probe ของตัวเอง เคยมีสองสำเนาที่คลาดเคลื่อนกัน: มีเพียงตัว
managed ที่เคยรันใน managed build และมีเพียงตัว repository ที่เคยโหลด
snapshot ที่ commit ไว้ — ดังนั้น managed deploy จึงให้บริการฐานข้อมูลว่างเปล่าและ
รายงานว่าสำเร็จ
เส้นทาง repository-only คือสิ่งที่อยู่รอดหลังการแยกตัว เป็นสิ่งที่ managed build ใช้ deploy
ผ่าน และเป็นสิ่งที่ rollback ใช้ มันไม่อ่าน URL ของ Dee Wan ไม่ออก build token และ
ไม่เรียก endpoint ของ CMS ใด ๆ มัน deploy commit ที่ได้รับมาตรงตามนั้น และบันทึก
commit ที่ deploy จริง มันส่ง git_sha, d1_uuid และ
worker_name กลับไปให้ผู้เรียก
สิ่งที่ทำให้ repository deploy ได้โดยไม่ต้องมี CMS
หัวข้อที่มีชื่อว่า “สิ่งที่ทำให้ repository deploy ได้โดยไม่ต้องมี CMS”สามไฟล์ หากขาดไฟล์ใดไฟล์หนึ่ง repository จะ build ได้แต่ไม่ให้บริการ สิ่งใดเลย
| ไฟล์ | โซน | สิ่งที่ไฟล์มี |
|---|---|---|
package-lock.json |
shared | tree ที่ resolve แล้วพร้อม integrity scripts/install-dependencies.mjs ต้องใช้ไฟล์นี้ |
data/published-snapshot.json |
generated | แถวที่เผยแพร่แล้ว ผูกกับไซต์ + artifact + manifest + content digest |
.github/workflows/deploy-from-repository.yml |
generated | checkout commit ที่ระบุตรงตัว, ติดตั้งแบบตรวจสอบ, build, resolve D1, migrate, โหลด snapshot, deploy, ตรวจสอบ |
การติดตั้งแบบตรวจสอบหมายถึง node scripts/install-dependencies.mjs [root] npm
ที่มาพร้อมกับ Node เวอร์ชันใน .nvmrc ต้องตรงกับ packageManager npm ci
แตกไฟล์โดยปิด script, tree ที่ติดตั้งแล้วถูก audit เทียบกับ
allowScripts ที่แน่นอน จากนั้น npm rebuild จะรันเฉพาะ script ที่อนุมัติแล้ว .nvmrc เป็น shared:
เขียนเมื่อยังไม่มี และไม่เขียนใหม่เด็ดขาด
lockfile เป็น SHARED ด้วยเหตุผลเดียวกับ package.json: adopter เพิ่ม
dependency ของตัวเอง และ emitter ต้องไม่ทิ้งสิ่งเหล่านั้น emitter
ยังคงรีเฟรชมันในทุกการรันด้วยการรัน npm install --package-lock-only บน
package.json ที่ merge แล้ว ดังนั้น lockfile และ manifest จึงไม่สามารถขัดแย้งกันได้
โหลด snapshot ลงในฐานข้อมูลด้วย:
npm run db:init -- --database ./graduated.db # local SQLite, migration firstnpm run data:load -- --d1 DB --config wrangler.deploy.jsonc # adopter D1Walkthrough: หนึ่ง route, หนึ่ง dependency, สร้างใหม่, deploy
หัวข้อที่มีชื่อว่า “Walkthrough: หนึ่ง route, หนึ่ง dependency, สร้างใหม่, deploy”ทุกคำสั่งด้านล่างเป็น script ที่โปรเจกต์ที่ถูกส่งออกมีอยู่แล้ว
1. ติดตั้งและเตรียมฐานข้อมูลที่ใช้งานได้
node scripts/install-dependencies.mjsnpm run db:init -- --database ./graduated.db2. เพิ่ม route แก้ไข src/owned/routes.ts — เพิ่ม
routes.post('/checkout', …) ตามข้างต้น ไม่มีอะไรอื่นต้องเชื่อมต่ออีก: src/app.ts
mount ownedRoutes ไว้ภายใต้ /api อยู่แล้ว
3. เพิ่ม dependency เพิ่มมันลงใน dependencies ใน package.json จากนั้น:
node scripts/install-dependencies.mjs4. พิสูจน์ในเครื่อง
npm run typechecknpm run build:serveDATABASE_PATH=./graduated.db SITE_ID=<your site id> \ ACCESS_CONFIG_FILE=./access.local.json PORT=8787 npm run serve:localจากนั้นใน shell อีกตัวหนึ่ง:
curl -i -X POST -H 'content-type: application/json' -d '{}' \ http://127.0.0.1:8787/api/checkoutdigest สำหรับ access.local.json ได้มาจาก npm run credential:digest ซึ่ง
อ่าน secret จาก stdin เพื่อไม่ให้ไปถึงประวัติของ shell หรือ ps เด็ดขาด
5. สร้างใหม่ ใช้ลำดับเดียวกับที่ managed build ใช้:
npm run regenerate # schema, app, security, local, manifest, Prisma client, portabilitynpm run migrate:emit # the next migration, append-onlynpm run typechecknode scripts/install-dependencies.mjs apps/sitenpm run --prefix apps/site checknpm run --prefix apps/site buildnpm run files:manifest # LAST: the ownership sidecar, from the tree that existsroute และ dependency ของคุณยังอยู่ที่เดิม git diff แสดงเฉพาะไฟล์ generated
และ migration ที่ถูกเพิ่มต่อท้าย
6. Bundle และ deploy
npm run build # the Worker bundle, via wrangler.build.jsoncการ deploy คือ workflow ไม่ใช่ script ในเครื่อง: commit จากนั้นรัน
.github/workflows/deploy-from-repository.yml สำหรับ commit นั้นพอดีด้วย
credential ของ Cloudflare ของคุณเอง มันติดตั้ง, build, resolve หรือสร้าง D1,
migrate, โหลด snapshot, deploy และตรวจสอบ Rollback คือ workflow เดียวกัน
กับ sha ที่เก่ากว่า npm run dev รัน Worker ในเครื่องโดยใช้ wrangler.jsonc
หากคุณต้องการ wrangler dev แทน
หลังการ deploy npm run verify:deployment จะถาม origin ที่ deploy แล้วว่า
ให้บริการเนื้อหาของ commit นี้ตรงทุกแถวหรือไม่ และ npm run verify:media
จะถามว่า projection ที่ commit ไว้ยังชี้ไปที่ Dee Wan หรือไม่
การสร้างสองรุ่นพร้อมการเปลี่ยน schema
หัวข้อที่มีชื่อว่า “การสร้างสองรุ่นพร้อมการเปลี่ยน schema”พิสูจน์โดย backend/test/graduate-adoption.test.ts — “keeps a developer’s own
file across a schema change”, “keeps rows the adopter wrote into their own table
across a schema change”, “regenerates after a schema change, appending to the
migration lineage”:
- สร้างและ deploy,
- แก้ไข
src/owned/และเพิ่มแถวลงในฐานข้อมูล, - เพิ่มฟิลด์ให้โมเดลใน CMS,
- สร้างใหม่
หลังขั้นตอนที่ 4: ไฟล์ owned เหมือนเดิมทุกไบต์, มี migration ใหม่ถูกเพิ่มต่อท้าย, migration เก่าไม่ถูกแตะต้อง และแถวที่มีอยู่ยังคงอยู่