เนื่องจากได้เห็นโพสต์ที่เกี่ยวกับ yarn berry แล้วเลยอยากลองที่จะ migrate จากตัวที่ใช้ pnpm ไป berry ก็เลยเกิดเป็นโพสต์นี้ครับ
ก่อนเริ่ม
จริงๆแล้วผมเคยได้ยินyarn (berry) มานานมาแล้วแต่ไม่เคยลองเพราะว่าช่วงนั้นผมเคยเห็น issue ที่ใช้แล้ว project ไม่สามารถรันได้เลยก็เลยคิดว่ารอสักพักค่อยมาลองสุดท้ายก็ลืม -.-
Timeline
ตั้งแต่เข้าสู่วงการ dev ผมก็เริ่มที่ npm -> yarn(classic) -> pnpm(ปัจจุบัน)
ขอย้อนไปตอนที่ใช้ yarn classic (หลังจากนี้จะขอย่อว่า classic) ผมใช้ feature นึงคือตัว worksapcesใช้มาประมาณ 3 ปีได้แล้วถ้านับไม่ผิด และก็เมื่อไม่นานมานี้ผมได้เห็นตัว pnpm เป็นที่พูดถึงกันก็เลยลองไปดูว่ามันเป็นยังไงมี feature ไหนบ้าง
หลังจากที่ไปดูว่าโดยรวมถือว่าโอเคเลยมีทุก feature ที่ผมใช้หลังจากนั้นโปรเจคช่วงๆหลังผมจะเป็น pnpm ทั้งหมด
ปัจจุบัน
ก่อนที่จะเข้าหัวข้อหลักคือ yarn berry มาดูตัวอย่าง structure ที่ผมใช้ pnpm แบบอย่างง่ายตาม example เลยก็ว่าได้แล้วจะแปลงเป็นในรูปแบบของ yarn berry
├── packages
│ └── moduleA
│ └── package.json ──
│ └── moduleB │
│ └── package.json │ moduleC เรียกใช้ moduleA
│ └── moduleC │
│ └── package.json __│
├── package.json
├── pnpm-workspace.yaml // <- pnpm เอาไว้ใช้ประกาศ workspace
- packages รวม modules ต่างๆไว้ในนี้, submodule จะเป็น typescript project ทั้งหมด
ตัวอย่างโค้ดของแบบ pnpm อยู่ repo นี้ -> example pnpm code
required nodejs >= 14.7
อธิบายเพิ่มเติมจาก code
- module{A,B,C} จะเป็น typescript ทั้งหมดโดยจะให้มัน compile ออกมาเป็น esm format รวมถึง *.d.ts เผื่อให้แต่ละ module มี type ของตัวมันเอง
- moduleC จะเรียกใช้ moduleA สังเกตได้จากตัว package.json และจะเรียกใช้ใน index.ts
ทั้งหมดนี้เมื่อ compile และ run จะทำงานได้ถูกต้อง
getTheBestSong
จาก moduleA จะเกิด Bug ไม่ว่าเราจะใส่ parameter ให้หรือไม่ใส่มันก็จะออกแต่ strawberry moon ❤️
Yarn (Berry)
หลังจากที่ไม่ได้พูดถึงเลยก็จะขอกลับมาพูดแบบย่อสักนิด
ข้อดีคร่าวๆของตัว berry
- เปลี่ยนการ resolve dependency ใหม่
- เพิ่ม ecosystem ของตัวเอง (plugin) e.g.
plugin-typescript
- constraints e.g. ในแต่ละ workspaces ต้องมี dependencies, library, devDependencies ที่เวอร์ชั่นเท่ากัน
- offline Cache
และแน่นอน workspaces
ข้อเสีย
- ส่วนตัวว่า doc ยังทำความเข้าใจได้อยากอยู่และตัวอย่างน้อย
อ่านเพิ่มเติมได้ที่ doc
ปรับ pnpm ให้อยู่ในรูปแบบ berry
tools
- set yarn version berry ด้วย command
yarn set version berry
- ลง vscode extension
- run command
yarn dlx @yarnpkg/sdks vscode
(เพื่อให้ vscode รู้การ resolve ที่ไม่ใช่จากตัว node_module)
จากโค้ด pnpm ข้างบน
- ลบ folder node_modules/ (แน่นอนจะไม่มี node_module แล้ว)
- ลบ pnpm-workspace.yaml, pnpm-lock.yaml
- เพิ่ม workspaces ใน package.json ใน root project
- ใน moduleC เรียกใช้ workspace moduleA ใน package.json
หลังจากทำตามข้างบนเรียบร้อยแล้วไปที่ root directory run command yarn
เพื่อ install dependency
หลังจากที่ install แล้วจะเห็นว่ามันจะไม่มี node_module อีกต่อไปแล้วแต่จะมาในรูปแบบของ javascript file แทน ในที่นี้คือ .pnp.cjs เปรียบเสมือน node_module นั่นเองแล้วที่นี้มันจะไปดู dependencies ที่ไหนละคำตอบก็คือในโฟลเดอร์ .yarn/cache สังเกตว่า berry จะโหลด deps มาในรูปแบบ zip
เรียบแล้วแล้วตอนนี้ project ของเราก็จะอยู่ในรูปแบบของ workspace(berry)
ทีนี้ก็ลอง build ทั้งโปรเจคโดย run command yarn workspaces foreach run build
มันจะแจ้งเตือนให้ลง plugin เพิ่ม (ecosystem อันใหม่) run command yarn plugin import workspace-tools
เมื่อลงเสร็จลอง build ใหม่ตาม command ข้างบนทีนี้ก็เป็นการเสร็จสิ้น
แต่เดี๋ยวก่อนนน...
ถ้าเกิดลองไปดูที่ moduleC จะเห็นว่ามันจะแจ้งเตือนหา moduleA ไม่เจอ ซึ่งผมก็ติดอยู่ตรงนี้แหละไม่ได้ไปต่อ ซึ่งลองไปดู issue ก็จะมีคนติดปัญหาที่คล้ายๆแบบนี้ก็เลยไม่ได้ไปลอง feature อื่นๆต่อ
แต่ถ้า project เป็น javascript ไม่ใช่ typescript สามารถทำงานได้ปกติ
โค้ดของ berry -> example berry code
สรุป
ปัญหาข้างบนเป็นในกรณีที่เราใช้ตัว workspaces แต่ถ้าไม่ได้ใช้ workspaces ตัว berry ทำงานได้ปกติ (resolve ได้ปกติ)
ทั้งหมดนี้ก็เป็นประสบการณ์ที่ผมได้เจอในการลองที่จะย้ายค่ายกลับมาใช้ yarn, ปัญหาที่เกิดขึ้นอาจจะเกิดที่ผมเซ็ตไม่ถูกต้องก็ได้ครับและถ้ามีโอกาสได้กลับมาแก้หรือมันแก้ไข้อะไรยังไงเรียบร้อยแล้วจะมาแชร์อีกทีครับ
ทั้งหมดนี้ถ้าผมสื่อสารผิดพลาดหรือทำให้งงยังไงก็ขอโทษด้วยนะครับจะพยายามปรับปรุงเรื่อยๆครับ ขอบคุณครับ 🙏
Top comments (0)