มารู้จัก Yarn workspaces กันดีกว่า
วันนี้มีทริปเล็กๆน้อยๆมาแนะนำครับ นั้นก็คือ Yarn Workspaces ปกติแล้วเวลาเราจัดการกับ Node.js app ที่มี node_modules
เยอะๆกันยังไงนะ ตัวอย่างเช่น มี folder หลัก ข้างในก็เป็น node api 1 folder มี react app ข้างในอีก 1 folder เวลาติดตั้ง dependencies มันก็จะแยก node_modules
กันแต่ละโฟลเดอร์ แต่ถ้าใช้ Yarn workspaces มันจะแชร์ node_modules
กันครับ เรียกได้ว่าทั้งสะดวก ทั้งประหยุดพื้นที่ Hard disk ได้เยอะเลย
การติดตั้งและใช้งาน Yarn
หน้าเว็บ Yarn มีขั้นตอนการติดตั้งอยู่ครับ สามารถเลือก OS และ Version ของ Yarn ได้เลย https://yarnpkg.com/en/docs/install
ส่วน Mac OS ก็ติดตั้งผ่าน Homebrew ง่ายๆเลยครับ
brew install yarn
สำหรับใครที่ไม่เคยใช้งาน Yarn ต้องบอกเลยว่าคำสั่งแทบเหมือนกันกับ NPM ครับ เช่น
- สร้างโปรเจ็คใหม่ ถ้า NPM จะเป็น
npm init
yarn init
- เพิ่ม library/dependency NPM จะเป็น
npm install NAME
yarn add PACKAGE_NAME
- ลบ Library
yarn remove PACKAGE_NAME
- Install dependencies (เท่ากับ
npm i
หรือnpm install
)
yarn
# หรือ
yarn install
รันคำสั่ง Script ใน package.json
ปกติใน NPM จะต้องใช้คำสั่ง run
(ถ้าไม่ใช่ default script) เช่น
npm run start-custom-server
แต่ Yarn ใช้ script ได้เลย ไม่ต้องมี run
yarn start-custom-server
มารู้จัก Workspaces
Workspaces เป็นเหมือนกับการ Setup Microservice คือโปรเจ็คนึงของเรา อาจจะมีหลายๆ project ย่อยๆ ตัว Workspaces จะมาช่วยให้เราจัดการกับ project ได้ง่ายขึ้น (หากใครเคยได้ยิน Lerna ซึ่ง repo ดังๆ เช่น Babel, Create React App, Jest ก็ใช้ Lerna แต่ว่า Lerna จะทำอะไรได้มากกว่า Workspace ซึ่งเน้นจัดการกับ dependencies ง่ายครับ)
เคยมั้ยที่เรา มี โฟลเดอร์นึง และภายในมี Node.js app อยู่ 3-4 ตัว เวลาเราจะเพิ่ม library เข้าไปใหม่ ก็ต้อง cd
เข้าไป install กลับมา/สลับ folder บ้าง อะไรพวกนี้?
cd projectA
yarn add awesomeLib
cd ../projectB
yarn add awesomeLib
cd ../projectC
yarn add awesomeLib
จะดีกว่ามั้ย ถ้าเรามีตัว base ไว้จัดการ project ย่อยๆ?
ก็เลยเกิดเป็นที่มาของ Yarn workspace นั่นเอง
Workspaces จะติดตั้งมาตั้งแต่ Yarn version 1.0.0 ขึ้นไป ฉะนั้นใครที่ Yarn version ต่ำจะไม่สามารถใช้ได้นะครับ
เริ่มต้นใช้งาน
ง่ายๆเลย เราต้องมี package.json
อยู่ที่ root folder ของเรา ตอนนี้จำลองง่ายๆ ผมจะสร้างrootFolder และภายในจะมี Node app 3 ตัวครับ
เริ่มแรกผมสร้าง folder และ ไฟล์ package.json
ขึ้นมาดังนี้
mkdir myAwesomeApp
touch package.json
และไฟล์ package.json
ใส่แบบนี้ลงไป
{
"private": true,
"workspaces": ["appA", "appB", "appC"]
}
Note:
"private": true
นั้นจำเป็นต้องใส่ครับ
ต่อมาที่ผมต้องการคือ สร้าง folder ขึ้นมา 3 ตัว ชื่อแบบที่ตั้งไว้ใน workspaces
ครับ คือ appA
, appB
และ appC
และข้างในทั้ง 3 folders ก็มีไฟล์ package.json
ของตัวเอง ระบุ name และ dependencies เอาไว้
{
"name": "appA",
"version": "1.0.0",
"dependencies": {
"express": "4.17.1"
}
}
ทั้ง 3 ไฟล์เหมือนกันหมด ต่างกันแค่ name
จากนั้นทำการสั่ง install ที่ตัว root folder
yarn install
yarn install v1.16.0
info No lockfile found.
[1/4] 🔍 Resolving packages...
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...
[4/4] 🔨 Building fresh packages...
จะเห็นว่าเรามีโฟลเดอร์ node_modules
ที่ถูกเพิ่มมาใน root folder ทีนี้ ไปสร้างไฟล์ app.js
ใน appA
เพื่อสร้างเว็บ Node.js ง่ายๆ ตัวนึง
const express = require('express')
const app = express()
app.get('/', (req, res) => {
res.json({ message: 'Running on appA' })
})
app.listen(5000, () => console.log('App is running'))
ในโฟลเดอร์ appA
มีแค่ไฟล์ package.json
และไฟล์ app.js
ด้านบน จากนั้นสั่ง
node app.js
ลองเปิดเว็บ browser http://localhost:5000
จะเห็นว่า App เรารันได้ปกติ ไม่มีปัญหาโดยมันแชร์ node_modules
จากตัว root folder นั่นเอง (ใน sub folder ไม่ต้องมี node_modules
เลย)
คราวนี้ ถ้าสมมติ แต่ละ folder มี app ของตัวเอง แล้วเวลาจะสั่ง start server ก็ต้องเข้าไปโฟลเดอร์แล้ว node app.js
ก็ไม่น่าสนุกเท่าไหร่
เราลองเพิ่ม script
ลงไปใน package.json
ของ appA
ดังนี้
{
"name": "appA",
"version": "1.0.0",
+ "scripts": {
+ "start": "node app.js"
+ },
"dependencies": {
"express": "4.17.1"
}
}
ปกติภายใน subfolder เวลาเราจะสั่งรัน เราจะใช้
yarn start
ทีนี้พอมี workspaces เราจะไปที่ root folder ครับ จากนั้นใช้คำสั่ง
yarn workspace FOLDER_NAME SCRIPT_NAME
# ตัวอย่าง
yarn workspace appA start
Note เราสามารถสั่งติดตั้ง dependencies ที่ root folder ได้ ด้วยคำสั่ง เช่น ติดตั้ง react ที่ appB
yarn workspace appB add react react-dom --dev
เราสามารถดู info ด้วยคำสั่ง
yarn workspaces info
จะได้รายละเอียดของ workspaces
yarn workspaces v1.16.0
{
"appA": {
"location": "appA",
"workspaceDependencies": [],
"mismatchedWorkspaceDependencies": []
},
"appB": {
"location": "appB",
"workspaceDependencies": [],
"mismatchedWorkspaceDependencies": []
},
"appC": {
"location": "appC",
"workspaceDependencies": [],
"mismatchedWorkspaceDependencies": []
}
}
Note: ถ้าหากว่า subfolder มีการกำหนด dependencies คนละ version กันเช่น express 4.17.0 กับ 4.17.1 ตัว yarn ก็จะไม่ link ไป
node_modules
ที่ตัว root นะครับ แต่จะติดตั้งnode_modules
ใน sub folder ที่เวอร์ชั่นไม่ตรง ฉะนั้นก็ระวังเรื่อง version ด้วยนะครับ
Reference
หวังว่าทริคเล็กๆน้อยๆนี้จะมีประโยชน์ไม่มากก็น้อยนะครับ ขอให้สนุกกับการเขียนโค๊ด ส่วนด้านล่างเป็น Repo เผื่อใครสนใจเข้าไปดูหรือลองรันเล่นๆก็ได้ แต่จริงๆก็ไม่ต่างจากบทความเท่าไหร่ :smile:
Happy Coding
- Authors
- Name
- Chai Phonbopit
- Website
- @Phonbopit