หากคุณเป็นนักพัฒนา Node.js คุณคงคุ้นเคยกับ npm และ Yarn แล้ว คุณอาจมีความคิดเห็นที่ชัดเจนเกี่ยวกับการใช้โปรแกรมใดโปรแกรมหนึ่งมากกว่าโปรแกรมอื่นด้วยซ้ำ เป็นเวลาหลายปีที่นักพัฒนาต้องดิ้นรนกับปัญหาที่ไม่จำเป็น — ในการจัดเก็บดิสก์และเวลาในการสร้าง — เมื่อทำงานกับตัวจัดการแพ็กเกจ Node.js โดยเฉพาะ npm
จากนั้น pnpm ก็เข้ามา ซึ่งเป็นตัวจัดการแพ็คเกจที่จัดการการจัดเก็บแพ็คเกจในรูปแบบที่แตกต่างกัน ช่วยประหยัดพื้นที่ของผู้ใช้และลดเวลาในการสร้าง pnpm อธิบายความแตกต่างนี้ ไว้ดังนี้:
“เมื่อคุณติดตั้งแพ็คเกจ เราจะเก็บแพ็คเกจนั้นไว้ในที่จัดเก็บส่วนกลางบนเครื่องของคุณ จากนั้นเราจะสร้างฮาร์ดลิงก์จากแพ็คเกจนั้นแทนที่จะคัดลอก สำหรับโมดูลแต่ละเวอร์ชัน จะมีสำเนาอยู่บนดิสก์เพียงหนึ่งชุดเท่านั้น เมื่อใช้ npm หรือ yarn ตัวอย่างเช่น หากคุณมีแพ็คเกจ 100 ชุดที่ใช้ lodash คุณจะมีสำเนา lodash บนดิสก์ 100 ชุด pnpm ช่วยให้คุณประหยัดพื้นที่ดิสก์ได้หลายกิกะไบต์!”
ไม่น่าแปลกใจที่ pnpm ได้รับความนิยมมากขึ้นเรื่อยๆ โดยมีนักพัฒนาซอฟต์แวร์จำนวนมากขึ้นเรื่อยๆ ที่เลือกใช้ pnpm เป็นตัวจัดการแพ็คเกจ นอกเหนือจากอัตราการนำไปใช้ที่เพิ่มขึ้นนี้ นักพัฒนาซอฟต์แวร์จำนวนมากที่รันแอปบน Heroku (เช่นเดียวกับฉัน) ก็ต้องการให้มีการรองรับ pnpm
โชคดีที่ pnpm พร้อมใช้งานผ่าน Corepack ซึ่งแจกจ่ายพร้อมกับ Node.js ดังนั้น ตั้งแต่เดือนพฤษภาคม 2024 pnpm จะพร้อมใช้งานใน Heroku แล้ว !
ในโพสต์นี้ เราจะกล่าวถึงสิ่งที่ต้องทำเพื่อเริ่มต้นใช้งาน pnpm บน Heroku และเราจะแสดงข้อดีบางประการเกี่ยวกับพื้นที่เก็บข้อมูลและระยะเวลาในการสร้างที่คุณจะได้รับจากการใช้งานด้วย
pnpm ถูกสร้างขึ้นเพื่อแก้ปัญหาตัวจัดการแพ็คเกจ Node.js ที่มีมาอย่างยาวนานเกี่ยวกับพื้นที่จัดเก็บที่ซ้ำซ้อนและประสิทธิภาพที่ต่ำใน การจัดการการอ้างอิง npm และ Yarn จะคัดลอกการอ้างอิงลงใน node_modules
ของแต่ละโครงการ ในทางกลับกัน pnpm จะเก็บแพ็คเกจทั้งหมดสำหรับทุกโครงการไว้ในที่จัดเก็บส่วนกลางเพียงแห่งเดียว จากนั้นจึงสร้างฮาร์ดลิงก์ไปยังแพ็คเกจเหล่านี้แทนที่จะคัดลอกไป ซึ่งหมายความว่าอย่างไร
สมมติว่าเรามีโครงการ Node.js ที่ใช้ lodash
โดยธรรมชาติแล้ว โครงการจะมีโฟลเดอร์ node_modules
พร้อมกับโฟลเดอร์ย่อยชื่อ lodash
ซึ่งเต็มไปด้วยไฟล์ โดยเฉพาะอย่างยิ่ง [email protected]
มีไฟล์ 639 ไฟล์และโฟลเดอร์ย่อยอีกโฟลเดอร์ชื่อ fp
ซึ่งมีไฟล์อีก 415 ไฟล์
นั่นเป็นไฟล์มากกว่าหนึ่งพันไฟล์สำหรับ lodash
เพียงอันเดียว!
ฉันสร้างโปรเจ็กต์ Node.js จำนวน 6 โปรเจ็กต์ ได้แก่ โปรเจ็กต์ pnpm 2 โปรเจ็กต์ npm 2 โปรเจ็กต์ และโปรเจ็กต์ Yarn 2 โปรเจ็กต์ โดยแต่ละโปรเจ็กต์ใช้ lodash
มาดูข้อมูลของไฟล์เพียงไฟล์เดียวในโฟลเดอร์การอ้างอิง lodash
กัน
~/six-projects$ ls -i npm-foo/node_modules/lodash/lodash.js 14754214 -rw-rw-r-- 544098 npm-foo/node_modules/lodash/lodash.js ~/six-projects$ ls -i npm-bar/node_modules/lodash/lodash.js 14757384 -rw-rw-r-- 544098 npm-bar/node_modules/lodash/lodash.js ~/six-projects$ ls -i yarn-foo/node_modules/lodash/lodash.js 14760047 -rw-r--r-- 544098 yarn-foo/node_modules/lodash/lodash.js ~/six-projects$ ls -i yarn-bar/node_modules/lodash/lodash.js 14762739 -rw-r--r-- 544098 yarn-bar/node_modules/lodash/lodash.js ~/six-projects$ ls -i pnpm-foo/node_modules/lodash/lodash.js 15922696 -rw-rw-r-- 544098 pnpm-foo/node_modules/lodash/lodash.js ~/six-projects$ ls -i pnpm-bar/node_modules/lodash/lodash.js 15922696 -rw-rw-r-- 544098 pnpm-bar/node_modules/lodash/lodash.js
ไฟล์ lodash.js
มีขนาดมากกว่าครึ่งเมกะไบต์เล็กน้อย เราไม่เห็นลิงก์แบบซอฟต์ลิงก์ ดังนั้นเมื่อดูครั้งแรก ดูเหมือนว่าแต่ละโปรเจ็กต์จะมีสำเนาไฟล์นี้เป็นของตัวเอง อย่างไรก็ตาม จริงๆ แล้วไม่ใช่เช่นนั้น
ฉันใช้ ls
พร้อมแฟล็ก -i
เพื่อแสดง อินโหนด ของไฟล์ lodash.js
คุณจะเห็นในโปรเจ็กต์ pnpm-foo
และ pnpm-bar
ว่าไฟล์ทั้งสองมีอินโหนดเดียวกัน ( 15922696
) โดยชี้ไปที่ไฟล์เดียวกัน! ไม่ใช่กรณีของ npm หรือ Yarn
ดังนั้น หากคุณมีโครงการจำนวน 12 โครงการที่ใช้ npm หรือ Yarn และโครงการเหล่านั้นใช้ lodash
คุณจะมีสำเนา lodash
ที่แตกต่างกันจำนวน 12 ชุด รวมถึงสำเนาจากการอ้างอิงอื่นๆ ในโครงการเหล่านั้นที่ใช้ lodash
เช่นกัน ใน pnpm โครงการและการอ้างอิงทุกโครงการที่ต้องการ lodash
เวอร์ชันเฉพาะนี้จะชี้ไปที่สำเนาสากลชุดเดียวชุดเดียวกัน
โค้ดสำหรับ [email protected]
มีขนาดไม่ถึง 5 MB คุณต้องการมีสำเนาสำรอง 100 ชุดบนเครื่องของคุณหรือสำเนารวมเพียงชุดเดียว?
ท้ายที่สุดแล้ว การติดตั้งสิ่งที่ต้องพึ่งพาด้วย pnpm จะเร็วขึ้นอย่างเห็นได้ชัด โดยต้องใช้พื้นที่ดิสก์และทรัพยากรน้อยลง สำหรับนักพัฒนาที่ทำงานในหลายโครงการหรือจัดการสิ่งที่ต้องพึ่งพาบนแพลตฟอร์มคลาวด์ pnpm นำเสนอวิธีจัดการแพ็คเกจที่กระชับและรวดเร็วขึ้น ซึ่งทำให้ pnpm เหมาะอย่างยิ่งสำหรับสภาพแวดล้อมการปรับใช้ที่มีประสิทธิภาพ เช่น Heroku
คุณพร้อมที่จะเริ่มใช้งานหรือยัง? มาดูกันว่าต้องทำอย่างไร
นี่คือเวอร์ชันของ Node.js ที่เรากำลังใช้งานอยู่บนเครื่องของเรา:
$ node --version v20.18.0
ดังที่เราได้กล่าวไปข้างต้น Corepack มาพร้อมกับ Node.js ดังนั้นเราเพียงแค่ต้องใช้ corepack
เพื่อเปิดใช้งานและใช้ pnpm จากนั้นเราสร้างโฟลเดอร์สำหรับโปรเจ็กต์ของเรา จากนั้นเรารันคำสั่งเหล่านี้:
~/project-pnpm$ corepack enable pnpm ~/project-pnpm$ corepack use pnpm@latest Installing [email protected] in the project... Already up to date Done in 494ms
ซึ่งจะสร้างไฟล์ package.json
ที่มีลักษณะดังนี้:
{ "packageManager": "[email protected]+sha512.22721b3a11f81661ae1ec68ce1a7b879425a1ca5b991c975b074ac220b187ce56c708fe5db69f4c962c989452eee76c82877f4ee80f474cebd61ee13461b6228" }
ซึ่งจะสร้างไฟล์ pnpm-lock.yaml
ด้วยเช่นกัน
ขั้นตอนต่อไปคือการเพิ่มการอ้างอิงลงในโครงการของเรา สำหรับการสาธิต เราจะคัดลอกรายการ dependencies
และ devDependencies
ที่พบในไฟล์ package.json
สำหรับ การทดสอบประสิทธิภาพ บน GitHub ตอนนี้ไฟล์ package.json
ของเรามีลักษณะดังนี้:
{ "version": "0.0.1", "dependencies": { "animate.less": "^2.2.0", "autoprefixer": "^10.4.17", "babel-core": "^6.26.3", "babel-eslint": "^10.1.0", ... "webpack-split-by-path": "^2.0.0", "whatwg-fetch": "^3.6.20" }, "devDependencies": { "nan-as": "^1.6.1" }, "packageManager": "[email protected]+sha512.22721b3a11f81661ae1ec68ce1a7b879425a1ca5b991c975b074ac220b187ce56c708fe5db69f4c962c989452eee76c82877f4ee80f474cebd61ee13461b6228" }
จากนั้นเราจึงทำการติดตั้งแพคเกจ
~/project-pnpm$ pnpm install
การใช้งาน pnpm นั้นค่อนข้างจะคล้ายกับ npm หรือ yarn และควรใช้งานง่าย ด้านล่างนี้คือตารางที่เปรียบเทียบการใช้งานที่แตกต่างกันของคำสั่งทั่วไป (นำมาจาก โพสต์นี้ )
ตอนนี้เราได้แสดงวิธีการสร้างโปรเจ็กต์และใช้งานด้วย pnpm แล้ว (มันค่อนข้างง่ายใช่ไหม) เราต้องการเปรียบเทียบเวลาในการสร้างสำหรับตัวจัดการแพ็คเกจต่างๆ เมื่อใช้งานบน Heroku เราตั้งค่าโปรเจ็กต์สามโปรเจ็กต์ที่มีการอ้างอิงเหมือนกัน โดยใช้ npm, Yarn และ pnpm
ขั้นแรกให้เราล็อกอินเข้าสู่ Heroku CLI ( heroku login
)
จากนั้นเราจะสร้างแอปสำหรับโครงการ เราจะแสดงขั้นตอนสำหรับโครงการ npm
~/project-npm$ heroku apps:create --stack heroku-24 npm-timing Creating ⬢ npm-timing... done, stack is heroku-24 https://npm-timing-5d4e30a1c656.herokuapp.com/ | https://git.heroku.com/npm-timing.git
เราพบ buildpack ที่เพิ่ม timestamps ในขั้นตอน build ใน Heroku log เพื่อให้เราสามารถคำนวณเวลา build จริงสำหรับโปรเจ็กต์ของเราได้ เราต้องการเพิ่ม buildpack นั้นลงในโปรเจ็กต์ของเราและให้ทำงานก่อน buildpack มาตรฐานสำหรับ Node.js เราทำได้โดยใช้คำสั่งสองคำสั่งต่อไปนี้:
~/project-npm$ heroku buildpacks:add \ --index=1 \ https://github.com/edmorley/heroku-buildpack-timestamps.git \ --app pnpm-timing ~/project-npm$ heroku buildpacks:add \ --index=2 heroku/nodejs \ --app npm-timing Buildpack added. Next release on npm-timing will use: 1. https://github.com/edmorley/heroku-buildpack-timestamps.git 2. heroku/nodejs Run git push heroku main to create a new release using these buildpacks.
เท่านี้ก็เรียบร้อย! จากนั้นเราก็ทำการ push โค้ดสำหรับโปรเจ็กต์ที่จัดการโดย npm ของเรา
~/project-npm$ git push heroku main ... remote: Updated 4 paths from 5af8e67 remote: Compressing source files... done. remote: Building source: remote: remote: -----> Building on the Heroku-24 stack remote: -----> Using buildpacks: remote: 1. https://github.com/edmorley/heroku-buildpack-timestamps.git remote: 2. heroku/nodejs remote: -----> Timestamp app detected remote: -----> Node.js app detected ... remote: 2024-10-22 22:31:29 -----> Installing dependencies remote: 2024-10-22 22:31:29 Installing node modules remote: 2024-10-22 22:31:41 remote: 2024-10-22 22:31:41 added 1435 packages, and audited 1436 packages in 11s remote: 2024-10-22 22:31:41 remote: 2024-10-22 22:31:41 184 packages are looking for funding remote: 2024-10-22 22:31:41 run `npm fund` for details remote: 2024-10-22 22:31:41 remote: 2024-10-22 22:31:41 96 vulnerabilities (1 low, 38 moderate, 21 high, 36 critical) remote: 2024-10-22 22:31:41 remote: 2024-10-22 22:31:41 To address issues that do not require attention, run: remote: 2024-10-22 22:31:41 npm audit fix remote: 2024-10-22 22:31:41 remote: 2024-10-22 22:31:41 To address all issues possible (including breaking changes), run: remote: 2024-10-22 22:31:41 npm audit fix --force remote: 2024-10-22 22:31:41 remote: 2024-10-22 22:31:41 Some issues need review, and may require choosing remote: 2024-10-22 22:31:41 a different dependency. remote: 2024-10-22 22:31:41 remote: 2024-10-22 22:31:41 Run `npm audit` for details. remote: 2024-10-22 22:31:41 npm notice remote: 2024-10-22 22:31:41 npm notice New minor version of npm available! 10.8.2 -> 10.9.0 remote: 2024-10-22 22:31:41 npm notice Changelog: https://github.com/npm/cli/releases/tag/v10.9.0 remote: 2024-10-22 22:31:41 npm notice To update run: npm install -g [email protected] remote: 2024-10-22 22:31:41 npm notice remote: 2024-10-22 22:31:41 remote: 2024-10-22 22:31:41 -----> Build remote: 2024-10-22 22:31:41 remote: 2024-10-22 22:31:41 -----> Caching build remote: 2024-10-22 22:31:41 - npm cache remote: 2024-10-22 22:31:41 remote: 2024-10-22 22:31:41 -----> Pruning devDependencies remote: 2024-10-22 22:31:44 remote: 2024-10-22 22:31:44 up to date, audited 1435 packages in 4s remote: 2024-10-22 22:31:44 remote: 2024-10-22 22:31:44 184 packages are looking for funding remote: 2024-10-22 22:31:44 run `npm fund` for details remote: 2024-10-22 22:31:45 remote: 2024-10-22 22:31:45 96 vulnerabilities (1 low, 38 moderate, 21 high, 36 critical) remote: 2024-10-22 22:31:45 remote: 2024-10-22 22:31:45 To address issues that do not require attention, run: remote: 2024-10-22 22:31:45 npm audit fix remote: 2024-10-22 22:31:45 remote: 2024-10-22 22:31:45 To address all issues possible (including breaking changes), run: remote: 2024-10-22 22:31:45 npm audit fix --force remote: 2024-10-22 22:31:45 remote: 2024-10-22 22:31:45 Some issues need review, and may require choosing remote: 2024-10-22 22:31:45 a different dependency. remote: 2024-10-22 22:31:45 remote: 2024-10-22 22:31:45 Run `npm audit` for details. remote: 2024-10-22 22:31:45 npm notice remote: 2024-10-22 22:31:45 npm notice New minor version of npm available! 10.8.2 -> 10.9.0 remote: 2024-10-22 22:31:45 npm notice Changelog: https://github.com/npm/cli/releases/tag/v10.9.0 remote: 2024-10-22 22:31:45 npm notice To update run: npm install -g [email protected] remote: 2024-10-22 22:31:45 npm notice remote: 2024-10-22 22:31:45 remote: 2024-10-22 22:31:45 -----> Build succeeded! ...
เราดูเวลาสำหรับขั้นตอนต่อไปนี้จนกระทั่งมีข้อความแจ้ง Build succeeded
ใกล้จะสิ้นสุด:
Installing dependencies
Build
Pruning devDependencies
Caching build
โดยรวมการใช้ npm สร้างนี้ใช้เวลา 16 วินาที
เราได้รันการตั้งค่าแบบเดียวกันสำหรับโครงการที่จัดการโดย pnpm โดยใช้ timings buildpack ด้วยเช่นกัน
~/project-pnpm$ heroku apps:create --stack heroku-24 pnpm-timing ~/project-pnpm$ heroku buildpacks:add \ --index=1 \ https://github.com/edmorley/heroku-buildpack-timestamps.git \ --app pnpm-timing ~/project-pnpm$ heroku buildpacks:add \ --index=2 heroku/nodejs \ --app pnpm-timing ~/project-pnpm$ git push heroku main … remote: 2024-10-22 22:38:34 -----> Installing dependencies remote: 2024-10-22 22:38:34 Running 'pnpm install' with pnpm-lock.yaml … remote: 2024-10-22 22:38:49 remote: 2024-10-22 22:38:49 dependencies: remote: 2024-10-22 22:38:49 + animate.less 2.2.0 remote: 2024-10-22 22:38:49 + autoprefixer 10.4.20 remote: 2024-10-22 22:38:49 + babel-core 6.26.3 … remote: 2024-10-22 22:38:51 -----> Build succeeded!
สำหรับการสร้างแบบเดียวกันกับ pnpm ใช้เวลาเพียง 7 วินาทีเท่านั้น
เราพบว่าการประหยัดเวลาไม่ได้เกิดขึ้นเฉพาะกับการติดตั้งครั้งแรกเท่านั้น การสร้างในครั้งต่อๆ ไปซึ่งใช้แคชการอ้างอิงก็เร็วขึ้นด้วย pnpm
ตอนที่ผมเริ่ม พัฒนา Node.js ครั้งแรก ผมใช้ npm เมื่อหลายปีก่อน ผมเปลี่ยนมาใช้ Yarn และนั่นคือสิ่งที่ผมใช้มาตลอด จนกระทั่งเมื่อไม่นานนี้ ตอนนี้ ผมเปลี่ยนมาใช้ pnpm แล้ว บนเครื่องในเครื่องของผม ผมสามารถเพิ่มพื้นที่ว่างในดิสก์ได้มาก การสร้างก็เร็วขึ้นด้วย และตอนนี้ ด้วยการรองรับ pnpm ของ Heroku ทำให้ผมปิดวงจรนี้ลงได้ เพื่อให้ผมสามารถใช้มันได้ตั้งแต่การพัฒนาในเครื่องไปจนถึงการใช้งานบนคลาวด์
สนุกกับการเขียนโค้ด!