ค่าที่ผมแนะนำให้ตั้งเป็นมาตรฐานคือ appVersionSource: "remote" เพื่อให้ EAS เก็บ version และ build number ไว้บนคลาวด์ แล้ว autoIncrement ใน production profile จะเพิ่ม build number ให้อัตโนมัติทุกครั้งที่ build ป้องกันเหตุการณ์ที่นักพัฒนาสองคน submit ทับด้วย build number เดียวกัน ซึ่งจะถูก App Store Connect ปฏิเสธทันที (เคยโดนมาเอง ตอน rebase แล้วลืม pull version ใหม่)
ผมแยก EXPO_PUBLIC_API_URL ตาม profile เสมอเพื่อให้ build ที่ทดสอบใน TestFlight ไม่ชี้ไป production API โดยบังเอิญ ค่า env ที่ขึ้นต้นด้วย EXPO_PUBLIC_ จะถูก inline ใน bundle ตอน build ดังนั้นห้ามใส่ secret หรือ API key ที่ละเอียดอ่อนในนี้ ให้ใช้ EAS Secrets ผ่าน eas secret:create สำหรับค่าที่ต้องป้องกันแทน
EAS Build ใช้ยังไง ตั้งแต่ build แรกถึง production
เมื่อ eas.json พร้อมแล้ว สั่ง build ด้วยคำสั่งเดียวต่อแพลตฟอร์ม ผมมักรัน parallel ทั้งสองเพื่อประหยัดเวลา queue โดยใช้ --non-interactive ใน CI หรือ local ก็ได้
npx eas build --profile production --platform ios
npx eas build --profile production --platform android
# หรือสั่งพร้อมกัน
npx eas build --profile production --platform all
ครั้งแรกที่รัน CLI จะถามเรื่อง credentials ผมแนะนำให้เลือก "Let Expo handle the process" เสมอสำหรับทีมขนาดเล็กถึงกลาง EAS จะสร้าง Apple distribution certificate, provisioning profile และ Android keystore เก็บไว้ใน secure vault ของ Expo เรียกใช้ได้จากทุกเครื่องโดยไม่ต้องส่งไฟล์ทาง Slack การเก็บ keystore เองยังทำได้ผ่าน eas credentials ถ้าทีมมีนโยบาย key custody ของตัวเอง
เมื่อโปรเจกต์มี native module นอกชุด Expo Go (เช่น react-native-mlkit, react-native-vision-camera ที่กำหนด config plugin) คุณต้อง build dev client ของตัวเอง สั่ง eas build --profile development --platform ios จะได้ .ipa ที่ติดตั้งบน iPhone จริงผ่าน TestFlight หรือ ad hoc แล้วเปิดด้วย Expo Go เวอร์ชัน custom ของคุณ ใช้คู่กับ npx expo start --dev-client เพื่อ reload bundle จาก Metro ปกติ ผมแนะนำให้ทุกโปรเจกต์ที่ตั้งใจไป production ใช้ custom dev client ตั้งแต่ต้น เพราะมันใกล้เคียงกับ binary ที่ลูกค้าใช้มากกว่า Expo Go มาตรฐาน
EAS Submit ขึ้น App Store และ Google Play อัตโนมัติ
EAS Submit รับ build จาก EAS Build แล้ว upload ขึ้น App Store Connect (iOS) หรือ Google Play Console (Android) โดยตรง ไม่ต้องเปิด Transporter หรือ Play Console UI สั่งงานด้วยคำสั่งเดียว
npx eas submit --profile production --platform ios --latest
npx eas submit --profile production --platform android --latest
ฟล็ก --latest หยิบ build ล่าสุดจาก EAS Build มาส่งโดยอัตโนมัติ ถ้าต้องการเลือก build เฉพาะให้ใช้ --id <build-id> ส่วน iOS ครั้งแรก CLI จะขอ App Store Connect API key (ไฟล์ .p8) ที่สร้างจาก App Store Connect → Users and Access → Keys หลังจากนั้น EAS จะเก็บ key ไว้ใช้ครั้งต่อ ๆ ไปโดยอัตโนมัติ
สำหรับ Android ต้องสร้าง service account ใน Google Cloud Console พร้อมสิทธิ์ "Release manager" บน Play Console แล้วชี้ path ของไฟล์ .json ใน eas.json ภายใต้ submit.production.android.serviceAccountKeyPath ผมแนะนำให้เก็บไฟล์นี้ไว้ในตำแหน่งที่ .gitignore exclude แล้วโหลดผ่าน secret store ของ CI แทน ห้าม commit เข้า repo เด็ดขาด เพราะมันเทียบเท่า master key ของ Google Play account ของคุณ
หลัง submit สำเร็จ build จะปรากฏใน TestFlight ภายใน 5-15 นาที (รอ Apple ทำ post-processing) ส่วน Google Play track ใช้เวลาน้อยกว่ามาก ราว 1-2 นาที สำหรับการตั้ง strategy การทดสอบก่อนกด release แนะนำให้ส่ง preview profile ขึ้น internal track ของ Google และ TestFlight internal group ก่อนเสมอ ทีมผมตั้งเงื่อนไขว่า build จะขึ้น production track ก็ต่อเมื่อผ่าน Maestro flow ครบทุก step บน TestFlight แล้วเท่านั้น
EAS Workflows ที่ออก GA ต้นปี 2026 ทำหน้าที่ orchestrator ผูก build, submit, update และ test เข้าด้วยกันในไฟล์ YAML วางไว้ใน .eas/workflows/release.yml ตัวอย่างที่ผมใช้กับโปรเจกต์ production
name: Release production
on:
push:
branches: ["main"]
jobs:
test:
type: test
steps:
- run: npm ci
- run: npm run typecheck
- run: npm test -- --ci
build_ios:
needs: [test]
type: build
params:
platform: ios
profile: production
build_android:
needs: [test]
type: build
params:
platform: android
profile: production
submit:
needs: [build_ios, build_android]
type: submit
params:
profile: production
ota_hotfix:
if: ${{ contains(github.event.head_commit.message, '[hotfix]') }}
type: update
params:
branch: production
message: ${{ github.event.head_commit.message }}
อีกตัวที่ลดต้นทุนได้คือ EAS Update ใช้ฟรี 1,000 monthly active users ในแผน Free และเพิ่มเป็น 50,000 MAU ในแผน Production ทำให้แอปขนาดเล็กถึงกลางใช้ OTA โดยไม่บวกค่าใช้จ่าย MAU นับเฉพาะเครื่องที่ดึง manifest จริง ไม่ใช่จำนวน install ทั้งหมด อ่านนิยามทางการได้ใน EAS Update introduction
Microsoft ประกาศปิดบริการ CodePush ในเดือนมีนาคม 2025 ทำให้ EAS Update เป็นทางเลือกหลักของชุมชน React Native ในปี 2026 EAS Update ใช้ runtime version policy แบบ fingerprint เพื่อป้องกัน update ไปทับ native build ที่ไม่เข้ากันโดยอัตโนมัติ ขณะที่ CodePush ใช้ deployment key คงที่ซึ่งจัดการ compatibility ด้วยตนเอง
ต้องมี Apple Developer account ของตัวเองก่อนใช้ EAS Submit ไหม?
จำเป็นสำหรับ iOS เสมอ คุณต้องมี Apple Developer Program ($99/ปี) เพื่อรับ App Store Connect API key ที่ EAS Submit ใช้สำหรับ upload build ส่วน Android ใช้ Google Play Developer account ($25 ครั้งเดียว) พร้อม service account JSON สำหรับสิทธิ์ Release Manager EAS เพียงจัดการ credential ให้ ไม่ได้แทน developer account