มารู้จัก 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 projectAyarn add awesomeLibcd ../projectByarn add awesomeLibcd ../projectCyarn 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 myAwesomeApptouch 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.0info 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 startNote เราสามารถสั่งติดตั้ง 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
-
Chai Phonbopit
เป็น Web Dev ในบริษัทแห่งหนึ่ง ทำงานมา 10 ปีกว่าๆ ด้วยภาษาและเทคโนโลยี เช่น JavaScript, Node.js, React, Vue และปัจจุบันกำลังสนใจในเรื่องของ Blockchain และ Crypto กำลังหัดเรียนภาษา Rust