ภาพวาดนากสีเขียวมิ้นต์ต้นฉบับกำลังเลื่อนกล่องโมดูลเข้ารางข้างโทรศัพท์จำลองบนโต๊ะทำงานสว่าง

React Native 0.87 ทดลองใช้ SwiftPM: ลดพิธี CocoaPods โดยยังไม่เสี่ยง Production

น้องกายEngineering

ทีม iOS ที่ใช้ React Native มักมีช่วง “แก้ JavaScript เสร็จแล้ว แต่ติด Ruby, Bundler หรือ pod install” React Native 0.87 เพิ่มเส้นทางทดลองผ่าน Swift Package Manager หรือ SwiftPM ซึ่งมากับ Xcode อยู่แล้ว เป้าหมายคือเชื่อม native dependencies โดยไม่ต้องใช้ CocoaPods ใน flow นั้น

คำสำคัญคือ experimental ครับ ประกาศ React Native 0.87 ระบุชัดว่า SwiftPM เป็นทางเลือกแบบ opt-in ขณะที่ CocoaPods ยังเป็นค่าเริ่มต้นและเส้นทางที่รองรับสำหรับ production เราจึงควรใช้ข่าวนี้เป็นโอกาสทำ compatibility lab ไม่ใช่สั่งย้ายแอปหลักทันที

WHY: ลด Toolchain Layer โดยไม่ทำลาย Xcode Project

SwiftPM path ใช้ prebuilt XCFramework ชุดเดียวกับที่ React Native เผยแพร่อยู่ คำสั่งจะ inject package references เข้า .xcodeproj เดิม แทนการสร้าง project ใหม่ ดังนั้น signing, capabilities และ build phases ที่ทีมตั้งไว้ควรอยู่ต่อ

ความต่างที่รู้สึกได้คือหลังติดตั้งครั้งแรก การเพิ่มหรือลบ native package จะให้ project ตรวจการเปลี่ยนแปลงและรัน autolinking ตอน build ไม่ต้องจำ pod install ทุกครั้ง เหมือนเปลี่ยนจากสมุดลงทะเบียนอีกเล่ม มาใช้รายการชิ้นส่วนในระบบประกอบเดียวกัน

แต่ layer ที่หายไปหนึ่งชั้นอาจเปิด incompatibility ของ library ที่ไม่เคยประกาศ Swift package จึงต้องทำ inventory ก่อน

HOW: ทดลองใน Branch ที่ย้อนกลับได้

คำสั่งจาก release note สำหรับนำ CocoaPods integration ออกแล้วติดตั้ง SwiftPM มีดังนี้ ตัวอย่างนี้ตรวจเฉพาะ shell syntax และ API เทียบเอกสาร 0.87 ไม่ได้อ้างว่า build ผ่าน simulator ใน repository บล็อกนี้

cd ios
npx react-native spm --deintegrate

ก่อนรันควร commit worktree ให้สะอาด เพื่อให้เห็นไฟล์ที่คำสั่งเปลี่ยนทั้งหมด หลังทดลองแล้ว npx react-native spm deinit ใช้ย้อนการเปลี่ยนได้ตามประกาศ แต่ผมยังแนะนำให้เก็บ diff และทดสอบ rollback จริง ไม่ควรเชื่อคำว่า reversible โดยยังไม่ลองกับ project ของเรา

หลัง fresh clone และใน CI ต้องรัน npx react-native spm หนึ่งครั้งก่อน build ซึ่งทำหน้าที่ใกล้กับ pod install เดิม ดังนั้นเวลาในเครื่องนักพัฒนาอาจลด แต่ CI ยังต้องมี explicit setup step และ cache ที่ออกแบบใหม่

Library ไหนคือคอขวด

community library ต้องมี Package.swift ถ้ายังไม่มี React Native CLI มี npx react-native spm scaffold เพื่อสร้างจาก podspec ได้ แต่ไฟล์ที่ generate เป็นจุดเริ่ม ไม่ใช่ใบรับรองว่า library รองรับ SwiftPM แล้ว

ทำตาราง native dependency แล้วแยกเป็น:

  • มี Package.swift และ upstream ทดสอบ React Native 0.87 แล้ว
  • scaffold ได้ แต่ยังต้อง build/test เอง
  • มี custom pod hook, script phase หรือ resource layout ที่ต้องวิเคราะห์เพิ่ม

เริ่ม proof-of-concept จากแอปเล็กที่ใช้ dependency ตัวแทนของแอปจริง เช่น camera, notification, storage และ analytics อย่างละหนึ่งตัว แล้ว build ทั้ง Debug/Release บน simulator กับ device จริง

Header เปลี่ยนเล็ก แต่ทำ Build แตกได้

เพื่อให้ SwiftPM จัด XCFramework ได้ตรงกติกา 0.87 เพิ่ม header-only frameworks และบังคับ namespace ชัดขึ้น import แบบ bare เช่น RCTAppDelegate.h ต้องเปลี่ยนเป็น path ใต้ React/ จุดนี้กระทบ native module ที่มี Objective-C/Objective-C++ มากกว่า JavaScript code

ค้น bare header imports ใน app และ private library ก่อนทดลอง จะช่วยแยกปัญหา integration ออกจากปัญหา compile และอย่ารวม migration Strict TypeScript API, AGP 9 และ SwiftPM ใน PR เดียว แม้อยู่ใน release เดียวกัน เพราะ failure surface จะกว้างเกินวินิจฉัย

Recap

SwiftPM ใน React Native 0.87 น่าสนใจเพราะลด Ruby/CocoaPods จากเส้นทางทดลอง และรักษา Xcode project เดิม แต่ยังเป็น experimental และ library ecosystem คือเงื่อนไขสำคัญ

พรุ่งนี้ทำ inventory native packages, เลือกแอปทดลองหนึ่งตัว และบันทึก build matrix กับ rollback ให้ครบ ถ้าหลักฐานผ่านหลายรอบ ค่อยวางแผน migration เมื่อทีม React Native ยกระดับเส้นทางนี้จาก experimental ครับ