การ Config Composer สำหรับ Project ขนาดใหญ่
เมื่อโปรเจกต์ PHP ของคุณเติบโตขึ้น การจัดการ Dependencies ด้วย Composer ก็จะมีความซับซ้อนมากขึ้นตามไปด้วย บทความนี้จะแนะนำเทคนิคต่างๆ ที่จะช่วยให้คุณ Config Composer ได้อย่างมีประสิทธิภาพสำหรับโปรเจกต์ขนาดใหญ่ โดยจะเน้นไปที่การจัดการ Dependencies, การใช้ Private Repositories และการ Optimizing Autoloading
Splitting Dependencies: แบ่ง Dependencies ตามหน้าที่การทำงาน
ในโปรเจกต์ขนาดใหญ่ มักจะมี dependencies จำนวนมาก ซึ่งอาจทำให้ไฟล์ composer.json ใหญ่และอ่านยาก การแบ่ง dependencies ออกเป็นส่วนๆ ตามหน้าที่การทำงาน (Functional Areas) จะช่วยให้การจัดการง่ายขึ้น และยังช่วยลดขนาดของ dependencies ที่ต้องติดตั้งในแต่ละ environment ได้อีกด้วย
เหตุผลเชิงออกแบบ:
- Readability: ไฟล์
composer.jsonที่เล็กลง อ่านง่ายขึ้น และเข้าใจได้ง่ายกว่า - Maintainability: การเปลี่ยนแปลง dependencies ในส่วนหนึ่งของโปรเจกต์ จะไม่ส่งผลกระทบต่อส่วนอื่นๆ
- Performance: ลดขนาดของ
vendordirectory โดยการติดตั้งเฉพาะ dependencies ที่จำเป็นสำหรับแต่ละ environment
วิธีการ:
- ระบุ Functional Areas: แบ่งโปรเจกต์ออกเป็นส่วนๆ ตามหน้าที่การทำงาน เช่น Core, Admin, API, Frontend
- สร้าง composer.json สำหรับแต่ละ Area: สร้างไฟล์
composer.jsonแยกกันสำหรับแต่ละ functional area โดยระบุ dependencies ที่จำเป็นสำหรับ area นั้นๆ เท่านั้น - ใช้ Composer Repository Manager: ใช้เครื่องมืออย่าง Packagist (public) หรือ Satis (private) เพื่อจัดการ packages เหล่านี้
ตัวอย่าง:
สมมติว่าเรามีโปรเจกต์ e-commerce ขนาดใหญ่ เราสามารถแบ่ง dependencies ได้ดังนี้:
- Core: Dependencies ที่จำเป็นสำหรับการทำงานพื้นฐานของระบบ เช่น Database, Authentication, Logging
- Admin: Dependencies ที่ใช้สำหรับส่วน Admin เช่น UI Framework, Form Builder
- API: Dependencies ที่ใช้สำหรับ API เช่น REST API Framework, Serialization Library
- Frontend: Dependencies ที่ใช้สำหรับ Frontend เช่น JavaScript Framework, CSS Framework
เราจะสร้างไฟล์ composer.json แยกกันสำหรับแต่ละส่วน:
// Core/composer.json
{
"name": "my-ecommerce/core",
"require": {
"php": "^7.4|^8.0",
"doctrine/orm": "^2.8",
"monolog/monolog": "^2.0"
},
"autoload": {
"psr-4": {
"MyEcommerce\\Core\\": "src/"
}
}
}
// Admin/composer.json
{
"name": "my-ecommerce/admin",
"require": {
"my-ecommerce/core": "*", // Dependency on Core
"symfony/form": "^5.0",
"symfony/validator": "^5.0"
},
"autoload": {
"psr-4": {
"MyEcommerce\\Admin\\": "src/"
}
},
"repositories": [
{
"type": "path",
"url": "../core" // Path to the Core package
}
]
}
ใน Admin/composer.json เราได้กำหนด dependency ไปยัง my-ecommerce/core โดยใช้ repositories เพื่อบอก Composer ว่า package นี้อยู่ที่ไหน (ในกรณีนี้คือ directory ../core)
Using Private Repositories: จัดการ Dependencies ภายในองค์กร
เมื่อคุณมี packages ที่พัฒนาขึ้นเองภายในองค์กร และไม่ต้องการเผยแพร่สู่สาธารณะ คุณสามารถใช้ Private Repositories เพื่อจัดการ dependencies เหล่านี้ได้
เหตุผลเชิงออกแบบ:
- Security: ป้องกันไม่ให้โค้ดภายในองค์กรรั่วไหลสู่ภายนอก
- Control: ควบคุมการเข้าถึง packages ได้อย่างเต็มที่
- Collaboration: ช่วยให้ทีมพัฒนาสามารถแชร์โค้ดและ dependencies ภายในองค์กรได้อย่างง่ายดาย
วิธีการ:
- เลือก Repository Manager: เลือกใช้ Repository Manager ที่เหมาะสมกับความต้องการของคุณ เช่น Satis, Toran Proxy, Cloudsmith, Private Packagist
- Config Repository ใน composer.json: เพิ่ม configuration ของ Private Repository ในไฟล์
composer.json - Authentication: กำหนด credentials สำหรับการเข้าถึง Private Repository
ตัวอย่าง:
สมมติว่าเราใช้ Satis เป็น Private Repository ที่ URL https://private.example.com เราจะต้องเพิ่ม configuration นี้ลงใน composer.json:
{
"repositories": [
{
"type": "composer",
"url": "https://private.example.com"
}
],
"require": {
"my-company/internal-package": "^1.0"
}
}
หาก Private Repository ต้องการ authentication เราสามารถกำหนด credentials ได้โดยใช้ environment variables หรือผ่าน configuration ใน Composer:
composer config --global repo.private.example.com.username myuser
composer config --global repo.private.example.com.password mypassword
Optimizing Autoloading: เพิ่มประสิทธิภาพการโหลด Class
Autoloading คือกลไกที่ช่วยให้ PHP สามารถโหลด class ได้โดยอัตโนมัติเมื่อมีการใช้งาน การ Optimizing Autoloading จะช่วยลดเวลาในการโหลด class และเพิ่มประสิทธิภาพของโปรเจกต์
เหตุผลเชิงออกแบบ:
- Performance: ลดเวลาในการโหลด class
- Memory Usage: ลดการใช้ memory โดยการโหลดเฉพาะ class ที่จำเป็น
วิธีการ:
- ใช้ Classmap Autoloading: สำหรับ classes ที่ไม่เป็นไปตามมาตรฐาน PSR-4 ให้ใช้ Classmap Autoloading
- ใช้
composer dump-autoload --optimize: คำสั่งนี้จะสร้าง optimized autoloader ที่เร็วกว่า - Autoloading ใน Production: ตรวจสอบให้แน่ใจว่า autoloader ถูก optimize ใน environment production
ตัวอย่าง:
หากเรามี classes ที่ไม่ได้อยู่ใน namespace ที่ถูกต้อง เราสามารถใช้ Classmap Autoloading ได้ดังนี้:
{
"autoload": {
"classmap": [
"src/LegacyClass.php",
"lib/"
]
}
}
หลังจากแก้ไข composer.json แล้ว ให้รันคำสั่ง:
composer dump-autoload --optimize
คำสั่งนี้จะสร้าง optimized autoloader ที่เร็วกว่า และเหมาะสำหรับใช้ใน environment production
ข้อควรระวัง: การใช้ --optimize จะใช้เวลานานกว่าการ dump autoload ปกติ ควรใช้ในขั้นตอน deploy หรือ build เท่านั้น
การ Config Composer สำหรับโปรเจกต์ขนาดใหญ่เป็นเรื่องที่ต้องใส่ใจในรายละเอียด แต่ด้วยเทคนิคที่กล่าวมาข้างต้น คุณจะสามารถจัดการ dependencies ได้อย่างมีประสิทธิภาพ เพิ่มความเร็วในการโหลด class และทำให้โปรเจกต์ของคุณทำงานได้อย่างราบรื่น