มีผู้เล่นหลักสามรายในพื้นที่ตัวจัดการแพ็คเกจ:
npm
Yarn
High-Performance npm (pnpm)
จริง ๆ แล้ว เรามีฟังก์ชันการทำงานที่คล้ายกันโดยพื้นฐานที่นำมาใช้กับตัวจัดการแพ็คเกจทั้งหมด ดังนั้นคุณมักจะตัดสินใจว่าจะใช้อันไหนโดยอิงจากข้อกำหนดที่ไม่สามารถใช้งานได้ ตัวจัดการแพ็คเกจ เช่น ความเร็วในการติดตั้ง ปริมาณการใช้พื้นที่จัดเก็บ หรือการใช้งานจริง
แน่นอนว่าวิธีที่คุณเลือกใช้ตัวจัดการแพ็คเกจแต่ละตัวจะแตกต่างกัน แต่โดยพื้นฐานแล้วทั้งหมดนั้นมีแนวคิดที่สอดคล้องกัน ตัวจัดการแพ็คเกจที่กล่าวมาข้างต้นทั้งหมดสามารถดำเนินการคำสั่งต่อไปนี้:
อย่างไรก็ตาม แม้จะมีสิ่งนี้ ตัวจัดการแพ็คเกจก็มีความแตกต่างกัน ตามเนื้อผ้า npm
และ Yarn
ติดตั้งการพึ่งพาในโฟลเดอร์ node_modules แบบแฟลต (ให้ความสนใจกับลำดับที่นี่ yarn
จะถูกเรียงต่อกันก่อน และก่อนหน้านั้น npm
จะเป็นแบบเรียกซ้ำ) แต่การปูกระเบื้องอาจทำให้เกิดปัญหาด้านความปลอดภัยตามมาได้
ความไม่แน่นอน ของโครงสร้างการพึ่งพา
อัลกอริธึมการทำให้เรียบนั้น ซับซ้อน และใช้เวลานานมาก
แพ็คเกจที่มีการขึ้นต่อกันที่ประกาศไว้
ยังคงสามารถ เข้าถึงได้อย่างผิดกฎหมาย ในโปรเจ็กต์
ดังนั้น pnpm
จึงได้แนะนำแนวคิดใหม่บางอย่างในโฟลเดอร์ node_modules
เพื่อจัดเก็บการขึ้นต่อกันอย่างมีประสิทธิภาพมากขึ้น Yarn Berry
ก้าวไปอีกขั้นด้วยการละทิ้งโหมด (PnP) ของ node_modules
โดยสิ้นเชิง (เพิ่มเติมเกี่ยวกับเรื่องนี้ในบทความอื่น)
ตัวจัดการแพ็คเกจที่เปิดตัวเร็วที่สุดคือ npm
ย้อนกลับไปในเดือนมกราคม 2010 มันกำหนดหลักการสำคัญของวิธีการทำงานของผู้จัดการแพ็คเกจในปัจจุบัน แต่เนื่องจาก npm
มีมานานกว่า 10 ปีแล้ว เหตุใดจึงมีตัวเลือกอื่นอีก ต่อไปนี้เป็นเหตุผลสำคัญบางประการว่าทำไมจึงเป็นเช่นนี้:
node_modules
มีอัลกอริธึมการแก้ไขการพึ่งพาที่แตกต่างกัน (ซ้อนกัน & เรียงต่อกัน, node_modules
เทียบกับโหมด PnP) และhoisting
)locking
ที่แตกต่างกัน (ประสิทธิภาพที่แตกต่างกัน เช่นรูปแบบที่เขียนโดย yarn
เอง)workspaces
) ซึ่งส่งผลต่อการบำรุงรักษาและความเร็วของ monorepos
ดำดิ่งลง ประวัติความเป็นมาของวิธีการกำหนดลักษณะเหล่านี้หลังจากการเพิ่มขึ้นของ npm
วิธีที่ Yarn Classic
แก้ไขปัญหาเหล่านี้บางส่วน pnpm
ขยายแนวคิดเหล่านี้อย่างไร และวิธีที่ Yarn Berry
ในฐานะผู้สืบทอดของ Yarn Classic
ทำลายแนวคิดและกระบวนการแบบดั้งเดิมเหล่านี้
npm
เป็นผู้ริเริ่มผู้จัดการแพ็คเกจ หลายๆ คนเข้าใจผิดว่า npm
เป็นตัวย่อของ "Node package manager" แต่ไม่ได้เป็นเช่นนั้น
การเปิดตัวครั้งนี้ถือเป็นการปฏิวัติเพราะก่อนหน้านี้ การขึ้นต่อกันของโปรเจ็กต์ถูกดาวน์โหลดและจัดการด้วยตนเอง npm
ได้แนะนำสิ่งต่างๆ เช่น ไฟล์และช่องข้อมูลเมตา การจัดเก็บการขึ้นต่อกันใน node_modules
สคริปต์แบบกำหนดเอง แพ็คเกจสาธารณะและส่วนตัว และอื่นๆ อีกมากมาย
ในปี 2020 GitHub เข้าซื้อกิจการ npm ดังนั้นโดยหลักการแล้ว npm
จะได้รับการจัดการโดย Microsoft ในขณะที่เขียน เวอร์ชันหลักล่าสุดคือ v8 ซึ่งเปิดตัวในเดือนตุลาคม 2021
ในเดือนตุลาคม 2559 Facebook ได้ประกาศความร่วมมือกับ Google และบริษัทอื่นๆ อีกจำนวนหนึ่งเพื่อพัฒนาตัวจัดการแพ็คเกจใหม่ (engineering.fb.com/2016/10/11/…) เพื่อจัดการกับความสอดคล้องที่มีอยู่ในขณะนั้นของ npm ปัญหาด้านความปลอดภัยและประสิทธิภาพ พวกเขาตั้งชื่อเส้นด้ายทดแทน
แม้ว่า Yarn
ยังคงได้รับการออกแบบทางสถาปัตยกรรมและออกแบบตามแนวคิดและกระบวนการมากมายของ npm
แต่ Yarn
ก็มีผลกระทบอย่างมีนัยสำคัญต่อฟิลด์ตัวจัดการแพ็คเกจ เมื่อเปรียบเทียบกับ npm
แล้ว Yarn
จะดำเนินการแบบขนานเพื่อเร่งกระบวนการติดตั้ง ซึ่งเป็นปัญหาสำคัญกับ npm
เวอร์ชันก่อนหน้า
Yarn
กำหนดมาตรฐานที่สูงขึ้นสำหรับการอ่านและการเขียน ความปลอดภัยและประสิทธิภาพ และคิดค้นแนวคิดมากมาย (ต่อมา npm
ได้ทำการปรับปรุงมากมายสำหรับสิ่งนี้) รวมถึง:
monorepo
รองรับLocking
)Yarn v1 ในการเข้าสู่โหมดการบำรุงรักษาใน 2020. ตั้งแต่นั้นมา ซีรีส์ v1.x ก็ถือเป็นเวอร์ชันดั้งเดิมและเปลี่ยนชื่อเป็น Yarn Classic
Yarn v2 (Berry) ผู้สืบทอดตำแหน่งเป็นสาขาการพัฒนาที่กระตือรือร้นมากขึ้น
pnpm
เวอร์ชัน 1 ที่มีประสิทธิภาพมากขึ้นของ pnpm
เปิดตัวในปี 2560 โดย Zoltan Kochan มันใช้แทน npm
ดังนั้นหากคุณมีโปรเจ็กต์ npm
คุณสามารถใช้ pnpm
ได้ทันที!
เหตุผลหลักที่ pnpm
ถูกสร้างขึ้นก็คือ npm
และ Yarn
นั้นซ้ำซ้อนมากในแง่ของโครงสร้างการจัดเก็บข้อมูลแบบพึ่งพาที่ใช้ในโปรเจ็กต์ แม้ว่า Yarn Classic
จะมีข้อได้เปรียบด้านความเร็วมากกว่า npm
แต่ก็ใช้วิธีการแก้ไขการพึ่งพาแบบเดียวกับที่ pnpm
ไม่มี: npm
และ Yarn Classic
ใช้ hoisting
เพื่อทำให้ node_modules
แบนลง
แทนที่จะปรับโครงสร้างก่อนหน้าให้เหมาะสม pnpm
แนะนำกลยุทธ์การแก้ปัญหาการพึ่งพาอื่น: โครงสร้างการจัดเก็บที่อยู่ตามเนื้อหา โฟลเดอร์ node_modules
ที่สร้างโดยวิธีนี้จริง ๆ แล้วอาศัยไดเร็กทอรี ~/.pnpm-store/
ที่ถูกเก็บไว้ทั่วโลกในโฟลเดอร์หลัก การขึ้นต่อกันแต่ละเวอร์ชันจะถูกจัดเก็บทางกายภาพหนึ่งครั้งในโฟลเดอร์ไดเร็กทอรีนี้ โดยสร้างที่อยู่ต้นทางเดียวเพื่อประหยัดพื้นที่ดิสก์ได้มาก
โครงสร้าง node_modules
เป็นโครงสร้างแบบซ้อนของการขึ้นต่อกันที่สร้างขึ้นโดยใช้ symlinks
(โดยที่แต่ละไฟล์/แพ็คเกจภายในโฟลเดอร์ถูกจัดเก็บผ่านฮาร์ดลิงก์) รูปต่อไปนี้จากเอกสารประกอบอย่างเป็นทางการแสดงให้เห็นสิ่งนี้ (รูปภาพที่ต้องกรอก: ลิงก์แบบอ่อนและแบบแข็ง)
อิทธิพลของ pnpm
ปรากฏให้เห็นในรายงานปี 2021: เนื่องจากนวัตกรรมในการจัดเก็บข้อมูลที่ระบุแอดเดรสของเนื้อหาได้ คู่แข่งจึงต้องการนำแนวคิด pnpm
มาใช้ เช่น โครงสร้างของลิงก์สัญลักษณ์และการจัดการดิสก์แพ็คเกจที่มีประสิทธิภาพ
Yarn 2 เปิดตัวในเดือนมกราคม 2020 และถูกเรียกเก็บเงินว่าเป็นการอัพเกรดครั้งใหญ่ของ Yarn
ดั้งเดิม ทีม Yarn
เรียกมันว่า Yarn Berry
เพื่อให้ชัดเจนยิ่งขึ้นว่าโดยพื้นฐานแล้วมันคือตัวจัดการแพ็คเกจใหม่ที่มีฐานโค้ดใหม่และหลักการใหม่
นวัตกรรมหลักของ Yarn Berry
คือแนวทางแบบปลั๊กแอนด์เพลย์ (PnP) เพื่อเป็นกลยุทธ์ในการซ่อมแซม node_modules แทนที่จะใช้กลยุทธ์ในการสร้าง node_modules
ให้สร้างไฟล์ .pnp.cjs
ด้วยตารางการค้นหาการพึ่งพา ซึ่งช่วยให้การจัดการการขึ้นต่อกันมีประสิทธิภาพมากขึ้น เนื่องจากเป็นไฟล์เดียวแทนที่จะเป็นโครงสร้างโฟลเดอร์ที่ซ้อนกัน นอกจากนี้ แต่ละแพ็กเกจจะถูกจัดเก็บไว้ในโฟลเดอร์ในรูปแบบไฟล์ zip แทนที่จะเป็น .yarn/cache/
และใช้พื้นที่ดิสก์น้อยกว่า node_modules
การเปลี่ยนแปลงทั้งหมดนี้เกิดขึ้นอย่างรวดเร็วจนทำให้เกิดข้อโต้แย้งมากมายหลังจากที่พวกเขาได้รับการปล่อยตัว การเปลี่ยนแปลงที่ทำลายล้างของ PnP ดังกล่าวทำให้ผู้ดูแลต้องอัปเดตแพ็คเกจที่มีอยู่เพื่อให้เข้ากันได้กับมัน การใช้แนวทาง PnP ใหม่เป็นค่าเริ่มต้นและการเปลี่ยนกลับเป็น node_modules
นั้นไม่ได้ตรงไปตรงมาในตอนแรก ซึ่งทำให้นักพัฒนาที่มีชื่อเสียงจำนวนมากไม่พิจารณาและวิพากษ์วิจารณ์ Yarn 2 ต่อสาธารณะ
ตั้งแต่นั้นมา ทีมงาน Yarn Berry
ได้แก้ไขปัญหาต่างๆ มากมายในการเผยแพร่ครั้งต่อๆ ไป เพื่อแก้ไขปัญหาความไม่เข้ากันของ PnP ทีมงานได้จัดเตรียมวิธีการเปลี่ยนโหมดการทำงานเริ่มต้นอย่างง่ายดาย ด้วยความช่วยเหลือของปลั๊กอิน node_modules การเปลี่ยนกลับไปใช้วิธี node_modules
แบบเดิมต้องการการกำหนดค่าเพียงบรรทัดเดียวเท่านั้น
นอกจากนี้ ระบบนิเวศน์ของ JavaScript ยังให้การสนับสนุน PnP เพิ่มมากขึ้นเรื่อยๆ และอย่างที่คุณเห็นในตารางความเข้ากันได้นี้ โครงการขนาดใหญ่บางโครงการได้เริ่มใช้ Yarn Berry
แล้ว
แม้ว่า Yarn Berry
ยังอายุน้อย แต่ก็ได้ส่งผลกระทบต่อพื้นที่ผู้จัดการแพ็คเกจแล้ว - pnpm
นำแนวทาง PnP มาใช้ในช่วงปลายปี 2020
ก่อนอื่นต้องติดตั้งตัวจัดการแพ็คเกจบนระบบโลคัลและ CI/CD ของผู้พัฒนาแต่ละรายก่อน
npm
จัดส่งพร้อมกับ Node.js
ดังนั้นจึงไม่จำเป็นต้องมีขั้นตอนเพิ่มเติม นอกเหนือจากการดาวน์โหลดตัวติดตั้ง Node.js สำหรับระบบปฏิบัติการของคุณแล้ว การใช้เครื่องมือ CLI เพื่อจัดการเวอร์ชันซอฟต์แวร์กลายเป็นเรื่องปกติไปแล้ว ในบริบทของ Node, Node Version Manager (nvm) หรือ Volta ได้กลายเป็นยูทิลิตี้ที่สะดวกมาก
คุณสามารถติดตั้ง Yarn 1 ได้หลายวิธี เช่น เป็นแพ็คเกจ npm
: .$ npm i -g yarn
หากต้องการย้ายจาก Yarn Classic ไปยัง Yarn Berry วิธีการที่แนะนำคือ:
ติดตั้งหรืออัปเดต Yarn Classic
เป็น
เวอร์ชัน
ใช้คำสั่ง
Yarn Set เวอร์ชัน berry
อย่างไรก็ตาม วิธีที่แนะนำในการติดตั้ง Yarn Berry ที่นี่คือผ่าน Corepack
Corepack ถูกสร้างขึ้นโดยนักพัฒนาของ Yarn Berry ความคิดริเริ่มนี้เดิมชื่อ Package Manager Manager (pmm) และถูกรวมเข้ากับ Node ใน LTS v16
ด้วยความช่วยเหลือของ Corepack ทำให้ Node เป็นตัวจัดการแพ็กเกจทางเลือกสำหรับ npm
ที่คุณไม่จำเป็นต้องติดตั้ง "แยกกัน" เนื่องจากมี Yarn Classic
, Yarn Berry
และ pnpm
binaries แผ่นชิมเหล่านี้อนุญาตให้ผู้ใช้เรียกใช้คำสั่ง Yarn และ pnpm โดยไม่ต้องติดตั้งอย่างชัดเจนก่อน และไม่ทำให้การกระจายโหนดยุ่งเหยิง
Corepack มาพร้อมกับ Node.js ≥ v16.9.0 ที่ติดตั้งไว้ล่วงหน้า อย่างไรก็ตาม สำหรับโหนดเวอร์ชันเก่า คุณสามารถใช้ ⬇️
npm install -g corepack
เพื่อเปิดใช้งาน Corepack ก่อนใช้งาน ตัวอย่างนี้แสดงวิธีเปิดใช้งานใน Yarn Berry v3.1.1
#คุณต้องเลือกเข้าร่วมก่อน เปิดใช้งาน $ corepack ติดตั้งแผ่นรอง # แล้ว แต่ต้องเปิดใช้งานเวอร์ชันที่เป็นรูปธรรม $ corepack เตรียมเส้นด้าย@3.1.1 --เปิดใช้งาน
คุณสามารถติดตั้ง pnpm
เป็นแพ็คเกจ npm
: $ npm i -g pnpm
คุณยังสามารถติดตั้ง pnpm โดยใช้ Corepack:
$ corepack เตรียม [email protected] --activate
ในส่วนนี้คุณจะเห็นคุณสมบัติหลักของผู้จัดการแพ็คเกจต่างๆ ได้อย่างรวดเร็ว คุณสามารถค้นหาไฟล์ที่เกี่ยวข้องในการกำหนดค่าตัวจัดการแพ็คเกจเฉพาะและไฟล์ใดที่สร้างขึ้นโดยขั้นตอนการติดตั้งได้อย่างง่ายดาย
ผู้จัดการแพ็คเกจทั้งหมดจะจัดเก็บข้อมูลเมตาที่สำคัญทั้งหมดไว้ในไฟล์ manifest ของโครงการ package.json นอกจากนี้ ไฟล์การกำหนดค่าระดับรูทยังสามารถใช้เพื่อตั้งค่าแพ็คเกจส่วนตัวที่แตกต่างกันหรือการกำหนดค่าการแก้ไขการพึ่งพาที่แตกต่างกัน
ในระหว่างขั้นตอนการติดตั้ง dependencies
จะถูกจัดเก็บไว้ในโครงสร้างไฟล์ เช่น node_modules
และสร้างไฟล์ locking
ส่วนนี้ไม่พิจารณาการตั้งค่าพื้นที่ทำงาน ดังนั้นตัวอย่างทั้งหมดจึงแสดงเฉพาะตำแหน่งเดียวที่จัดเก็บการขึ้นต่อกัน
โดยใช้ $ npm install
หรือ $ npm i
จะสร้างไฟล์ package-lock.json
และโฟลเดอร์ node_modules
นอกจากนี้ยังมีไฟล์ที่กำหนดค่าได้ เช่น .npmrc
ที่สามารถวางไว้ในไดเร็กทอรีระดับรูทได้ ดูส่วนถัดไปสำหรับข้อมูลเพิ่มเติมเกี่ยวกับ locking
ไฟล์
- ├── node_modules/ ├── .npmrc ├── แพ็คเกจ-lock.json └── package.json
ที่รัน $ yarn
จะสร้างไฟล์ yarn.lock
และโฟลเดอร์ node_modules
ไฟล์ .yarnrc
ยังสามารถเป็นตัวเลือกการกำหนดค่าได้ และ Yarn Classic
ยังรองรับไฟล์ .npmrc
อีกด้วย หรือคุณสามารถใช้โฟลเดอร์แคช .yarn/cache/
และ Yarn Classic
เวอร์ชันล่าสุดที่จัดเก็บไว้ใน .yarn/releases/
- ├── .เส้นด้าย/ │ ├── แคช/ │ └── เปิดตัว/ │ └── เส้นด้าย-1.22.17.cjs ├── node_modules/ ├── .yarnrc ├── แพ็คเกจ json └── Yarn.lock
เนื่องจากโหมดการติดตั้งพิเศษนี้ คุณจะต้องจัดการกับไฟล์และโฟลเดอร์ในโปรเจ็กต์ Yarn Berry
ของคุณมากกว่าผู้จัดการแพ็คเกจอื่นๆ บางส่วนเป็นทางเลือกและบางส่วนเป็นข้อบังคับ
Yarn Berry
ไม่รองรับ .npmrc
หรือ .yarnrc
อีกต่อไป แต่ต้องใช้ .yarnrc.yml สำหรับเวิร์กโฟลว์แบบดั้งเดิมของการสร้างโฟลเดอร์ node_modules
คุณต้องจัดเตรียมการกำหนดค่า nodeLinker
เพื่อใช้การกำหนดค่า node_modules
หรือ pnpm
(ฉันไม่เข้าใจส่วนนี้)
# .yarnrc.yml nodeLinker: node-modules # หรือ pnpm
ที่รัน $ yarn
จะติดตั้งการขึ้นต่อกันทั้งหมดในโฟลเดอร์ node_modules
และไฟล์ yarn.lock
จะถูกสร้างขึ้น ซึ่งใหม่กว่าแต่เข้ากันไม่ได้กับ Yarn Classic
นอกจากนี้ โฟลเดอร์ .yarn/cache/
จะถูกสร้างขึ้นสำหรับการติดตั้งแบบออฟไลน์ โฟลเดอร์นี้เป็นทางเลือกและใช้เพื่อจัดเก็บเวอร์ชันของ Yarn Berry
ที่โปรเจ็กต์ใช้
- ├── .เส้นด้าย/ │ ├── แคช/ │ └── เปิดตัว/ │ └── เส้นด้าย-3.1.1.cjs ├── node_modules/ ├── .yarnrc.yml ├── แพ็คเกจ json └── Yarn.lock
ไม่ว่าจะเป็นโหมดเข้มงวดหรือโหมด Loose สำหรับ PnP การรัน $ yarn
ด้วย .pnp.cjs
และ yarn.lock
จะสร้าง .yarn/cache/
และ .yarn/unplugged
PnP เข้มงวดเป็นโหมดเริ่มต้น หากคุณต้องการกำหนดค่าโหมดหลวม คุณต้องเปิดใช้งานในรูปแบบต่อไปนี้:
# .yarnrc.yml nodeLinker: pnp pnpMode: loose
ในโครงการ PnP นอกเหนือจากโฟลเดอร์ releases
แล้ว โฟลเดอร์ .yarn
yarn ยังมีแนวโน้มที่จะมีโฟลเดอร์ sdk/
ที่ให้การสนับสนุน IDE อีกด้วย .yarn
อาจมีโฟลเดอร์เพิ่มเติมก็ได้ ทั้งนี้ขึ้นอยู่กับกรณีการใช้งานของคุณ
- ├── .เส้นด้าย/ │ ├── แคช/ │ ├── เปิดตัว/ │ │ └── เส้นด้าย-3.1.1.cjs │ ├── sdk/ │ └── ถอดปลั๊กแล้ว/ ├── .pnp.cjs ├── .pnp.loader.mjs ├── .yarnrc.yml ├── แพ็คเกจ json └── Yarn.lock`สถานะเริ่มต้นของ
pnpm
npm
หรือโปรเจ็กต์ Yarn Classic
ต้องใช้ไฟล์ package.json
ด้วย หลังจากติดตั้งการพึ่งพาโดยใช้ $ pnpm i
ผลลัพธ์ในโฟลเดอร์ node_modules
แต่โครงสร้างของมันแตกต่างอย่างสิ้นเชิงเนื่องจากเนื้อหาเป็นที่เก็บข้อมูลที่สามารถกำหนดแอดเดรสได้
pnpm
ยังสร้างไฟล์ล็อคของตัวเอง pnp-lock.yml
คุณสามารถจัดเตรียมการกำหนดค่าเพิ่มเติมได้โดยใช้ไฟล์เสริม .npmrc
- ├── node_modules/ │ └── .pnpm/ ├── .npmrc ├── แพ็คเกจ json └── ไฟล์ล็อค pnpm-lock.yml
ดังที่กล่าวไว้ในส่วนก่อนหน้า ตัวจัดการแพ็คเกจทุกตัวจะสร้างไฟล์ล็อค
ไฟล์ lock
จะจัดเก็บเวอร์ชันที่แน่นอนของการขึ้นต่อกันทั้งหมดที่ติดตั้งโดยโปรเจ็กต์ของคุณ ซึ่งช่วยให้สามารถติดตั้งที่คาดเดาและกำหนดได้มากขึ้น ไฟล์ lock
นี้มีความสำคัญเนื่องจากเวอร์ชันที่ต้องพึ่งพามีแนวโน้มที่จะได้รับการประกาศด้วยช่วงเวอร์ชัน (เช่น ≥ v1.2.5) และหากคุณไม่ "ล็อก" เวอร์ชันของคุณ เวอร์ชันจริงที่ติดตั้งอาจแตกต่างกัน
ไฟล์ล็อคบางครั้งยังเก็บเช็คซัม (แฮชอย่างที่ฉันจำได้) ซึ่งเราจะกล่าวถึงในเชิงลึกมากขึ้นในส่วนความปลอดภัย
เริ่มต้นจาก npm
v5+ การล็อคไฟล์จะเป็นฟังก์ชันหลักของ npm
( package-lock.json
) เสมอ ใน pnpm
จะเป็น pnpm-lock.yaml
yarn.lock
ใน Yarn Berry
จะปรากฏในรูปแบบ YAML ใหม่
ในส่วนก่อนหน้านี้ เราเห็นวิธีการดั้งเดิมในการติดตั้งการพึ่งพาในโครงสร้างโฟลเดอร์ node_modules
นี่คือวิธีแก้ปัญหาที่ใช้โดย npm
, Yarn Classic และ pnpm ( pnpm
มีประสิทธิภาพมากกว่าวิธีอื่น)
Yarn Berry
ทำสิ่งที่แตกต่างออกไปในโหมด PnP แทนที่จะเป็นโฟลเดอร์ node_modules
การขึ้นต่อกันจะถูกจัดเก็บไว้ในไฟล์ zip โดยเป็นการรวมกันของไฟล์ .yarn/cache/
และ .pnp.cjs
เป็นการดีกว่าที่จะวางไฟล์ล็อคเหล่านี้ไว้ภายใต้การควบคุมเวอร์ชัน เนื่องจากสมาชิกในทีมทุกคนจะติดตั้งเวอร์ชันเดียวกัน ดังนั้นจึงช่วยแก้ปัญหา "ใช้งานได้กับเครื่องของคุณและของฉัน"
ตารางต่อไปนี้เปรียบเทียบคำสั่ง CLI ต่างๆ ที่มีอยู่ใน npm
, Yarn Classic
, Yarn Berry
และ pnpm
นี่ไม่ใช่รายการทั้งหมด แต่เป็นรายการโกง ส่วนนี้ไม่ครอบคลุมถึงคำสั่งที่เกี่ยวข้องกับเวิร์กโฟลว์
npm
และ pnpm
มีคำสั่งเฉพาะกิจและนามแฝงตัวเลือกมากมาย ซึ่งหมายความว่าคำสั่งสามารถมีชื่อที่แตกต่างกันได้ เช่น $ npm install
กับ $ npm add
นอกจากนี้ ตัวเลือกคำสั่งจำนวนมากยังมีเวอร์ชันย่อ เช่น -D
แทน --save-dev
ในตาราง ฉันเรียกนามแฝงเวอร์ชันย่อทั้งหมด ด้วยการใช้ตัวจัดการแพ็คเกจแต่ละตัว คุณสามารถเพิ่ม อัพเดต หรือลบการขึ้นต่อกันหลายรายการได้
ตารางนี้ครอบคลุมถึงคำสั่งการจัดการการขึ้นต่อกันที่ใช้ในการติดตั้งหรืออัพเดตการขึ้นต่อกันทั้งหมดที่ระบุใน package.json
การดำเนินการ | npm | Yarn Classic | Yarn Berry | pnpm | |
---|---|---|---|---|---|
ติดตั้ง deps ใน package.json | นามแฝงการติดตั้ง npm: i, เพิ่ม | การติดตั้งเส้นด้ายหรือเส้นด้าย | เช่น | นามแฝงการติดตั้ง pnpm แบบคลาสสิก: ฉัน | |
อัปเดต deps ใน package.json acc นามแฝง | การอัปเดต npm: ขึ้น, อัปเกรด | เส้นด้ายอัพเกรด | เส้นด้าย semver up (ผ่านปลั๊กอิน) | นามแฝงอัปเดต pnpm: อัป | |
เดต deps ใน package.json เป็น | อัปเกรดเส้นด้าย | N/A | ล่าสุด - อัปเดตเส้นด้าย | ล่าสุดอัปเดต pnpm - นามแฝงล่าสุด: -L | |
อัป | เด | ต | deps acc | semver up ตอบสนอง | pnpm up อัปเดตการ |
ตอบสนอง deps เป็นการ | อัปเดต npm ล่าสุด react@ล่าสุด | อัปเกรดเส้นด้ายreact | - เส้นด้ายล่าสุด | ขึ้น ตอบสนองpnpm ขึ้น -L | อัปเด|
ตปฏิกิริยา deps แบบโต้ตอบ | N/A | อัปเกรดเส้นด้ายแบบโต้ตอบ | อัปเกรดเส้นด้ายแบบโต้ตอบ (ผ่านปลั๊กอิน) | $ pnpm ขึ้น --นามแฝงเชิงโต้ตอบ: -ฉัน | |
เพิ่มรันไทม์ deps | npm ฉันตอบสนอง | เส้นด้าย เพิ่มปฏิกิริยา | เช่น Classic | pnpm เพิ่ม react | |
เพิ่ม dev deps | npm i -D babel นามแฝง: --save-dev | เส้นด้ายเพิ่ม -D babel นามแฝง: --dev | เช่น Classic | pnpm เพิ่ม -D babel alias: --save-dev | |
เพิ่ม deps ใน package.json โดยไม่มี semver | npm i -E react alias: --save-exact | Yarn add -E react alias: --exact | like Classic | pnpm add -E react alias: - - บันทึก - บันทึก | |
ถอนการติดตั้งที่แน่นอน deps และลบออกจาก package.json | npm ถอนการติดตั้งนามแฝงตอบสนอง: ลบ, rm, r, ยกเลิก, ยกเลิกการเชื่อม | โยงเส้นด้ายลบปฏิกิริยา | เช่นคลาสสิก | pnpm ลบนามแฝงปฏิกิริยา: rm, un, ถอนการติดตั้งถอน | |
การติดตั้ง deps โดยไม่ต้องอัปเดตแพ็คเกจ json | npm Uninstall --no-save | N/A | N/A | N/A |
ตัวอย่างต่อไปนี้แสดงวิธีจัดการแพ็คเกจระหว่างการพัฒนา ข้อกำหนดที่ใช้ในตาราง:
- แพ็คเกจ: การพึ่งพาหรือไบนารี
- ไบนารี: เครื่องมือดำเนินการจาก
node_modules/.bin/
หรือ.yarn/cache/
(PnP)
สิ่งสำคัญคือต้องเข้าใจว่า Yarn Berry
อนุญาตให้เราดำเนินการใน package.json
หรือ Expose เท่านั้น ไฟล์ไบนารีที่ระบุใน bin/
file
การดำเนินการ | npm | Yarn Classic | Yarn Berry | pnpm |
---|---|---|---|---|
ติดตั้งแพ็คเกจทั่วโลก | npm i -g ntl นามแฝง: --global | Yarn global เพิ่ม ntl | N/A (ลบออกทั่วโลก) | pnpm add --global ntl |
แพ็คเกจอัพเดตทั่วโลก | npm update -g ntl | Yarn global อัพเกรด ntl | N /A | การอัปเดต pnpm --global ntl |
ลบแพ็คเกจทั่วโลก | npm ถอนการติดตั้ง -g ntl | เส้นด้ายทั่วโลกลบ ntl | N/A | pnpm ลบ --global ntl |
เรียกใช้ไบนารีจากเทอร์มินัล | npm exec ntl | เส้นด้าย ntl | เส้นด้าย ntl | pnpm ntl |
เรียกใช้ไบนารีจากสคริปต์ | ntl | ntl | ntl | ntl |
การดำเนินการแพ็คเกจแบบไดนามิก | npx ntl | ไม่มี | เส้นด้าย dlx ntl | pnpm dlx ntl |
เพิ่มรันไทม์ deps | npm ฉันตอบสนอง | เส้นด้ายเพิ่มการตอบสนอง | เช่นคลาสสิก | pnpm เพิ่มการตอบสนอง |
เพิ่ม dev deps | npm i -D นามแฝงของ babel: --save-dev | เส้นด้ายเพิ่ม -D นามแฝงของ babel: --dev | เช่น Classic | pnpm add -D babel alias: --save-dev |
เพิ่ม deps ใน package.json โดยไม่มี semver | npm i -E react alias: --save-exact | Yarn add -E react alias: --exact | เหมือน Classic | pnpm เพิ่ม -E react alias: --save-exact |
ถอนการติดตั้ง deps และลบออกจาก package.json | npm ถอนการติดตั้ง react alias: ลบ, rm, r, un, ยกเลิก | การเชื่อมโยงเส้นด้าย ลบปฏิกิริยา | เหมือน Classic | pnpm ลบนามแฝงของปฏิกิริยา: rm, un, ถอนการติดตั้ง | ถอน
การติดตั้ง deps ไม่มีการอัปเดต package.json | ถอนการติดตั้ง npm --no-save | N/A | N/A | N/A |
ตารางนี้ครอบคลุมคำสั่งในตัวที่มีประโยชน์บางคำสั่ง หากไม่มีคำสั่งอย่างเป็นทางการ คำสั่งของบุคคลที่สามมักจะสามารถใช้ได้ผ่านแพ็คเกจ npm
หรือปลั๊กอิน Yarn Berry
การดำเนินการ | npm | Yarn Classic | Yarn Berry | pnpm |
---|---|---|---|---|
เผยแพร่ | npm เผยแพร่ | เส้นด้าย เผยแพร่ | เส้นด้าย npm เผยแพร่ | pnpm เผยแพร่ |
รายการที่ติดตั้ง deps | npm ls นามแฝง: รายการ, la, ll | รายการเส้นด้าย | นามแฝงรายการ pnpm: | |
รายการ ls ที่ล้าสมัย deps | npm เส้นด้ายที่ล้าสมัย | เส้นด้ายที่ล้าสมัย | อัปเกรด- | โต้ตอบpnpm |
ข้อมูลการพิมพ์ที่ล้าสมัยเกี่ยวกับ deps | npm อธิบายนามแฝง ntl: ทำไม | เส้นด้าย ทำไม ntl | ถึงชอบ Classic | pnpm ทำไม ntl |
init โครงการ | npm init -y นามแฝง init (โต้ตอบ) npm: - -yes | Yarn init -y Yarn init นามแฝง (แบบโต้ตอบ): --yes | Yarn init | pnpm init -y pnpm init นามแฝง (แบบโต้ตอบ): --yes |
ข้อมูลใบอนุญาตการพิมพ์ | N/A (ผ่านแพ็คเกจบุคคลที่สาม) | รายการใบอนุญาตเส้นด้าย | N/ A (หรือผ่านปลั๊กอิน ปลั๊กอินอื่นๆ) | N/A (ผ่านแพ็คเกจบุคคลที่สาม) |
อัปเดตเวอร์ชันตัวจัดการแพ็คเกจ | N/A (ด้วยเครื่องมือของบุคคลที่สาม เช่น nvm) | ด้วย npm: ชุดนโยบายเส้นด้าย เวอร์ชัน 1.13.0 | พร้อม Corepack : ชุดเส้นด้ายเวอร์ชัน 3.1.1 | N/A (พร้อม npm, Corepack) |
ดำเนินการตรวจสอบความปลอดภัย | การตรวจสอบ npm | การตรวจสอบ | เส้นด้าย การตรวจสอบเส้นด้าย npm | การตรวจสอบ pnpm |
เพิ่ม deps ใน package.json โดยไม่มี semver | npm i -E นามแฝงตอบสนอง: --save-exact | thread add -E react alias: -- | เหมือนกับ Classic | pnpm add -E react alias: --save-exact |
ถอนการติดตั้ง deps และลบออกจาก package.json | npm ถอนการติดตั้ง react alias: ลบ, rm, r, un, ยกเลิกการเชื่อม | โยงเส้นด้าย ลบปฏิกิริยา | เช่น Classic | pnpm ลบนามแฝงการตอบสนอง: rm, un, ถอนการติดตั้ง ถอน |
การติดตั้ง deps โดยไม่มีการอัปเดตของ package.json | ถอนการติดตั้ง npm --no-save | N/A | N/A | N/A |
การกำหนดค่าตัวจัดการแพ็คเกจเกิดขึ้นใน package.json
และไฟล์การกำหนดค่าเฉพาะของคุณ
monorepo
ใด คอนฟิกูเรชันส่วนใหญ่เกิดขึ้นในไฟล์คอนฟิกูเรชันส่วนตัว . .npmrc
หากคุณต้องการใช้ฟีเจอร์ workspaces
ของ npm
คุณต้องเพิ่มฟิลด์ข้อมูลเมตาของพื้นที่ทำงานใน package.json
เพื่อบอก npm ว่าจะหาโปรเจ็กต์ย่อยหรือโฟลเดอร์พื้นที่ทำงานได้จากที่ไหน
- "พื้นที่ทำงาน": [ "ตะขอ", "ยูทิลิตี้" - }
ผู้จัดการแพ็คเกจทุกคนสามารถใช้รีจิสทรี npm
สาธารณะได้ คุณอาจต้องการนำมาใช้ซ้ำโดยไม่ต้องเผยแพร่ไปยังทะเบียนสาธารณะ คุณสามารถกำหนดค่านี้ให้เป็นส่วนตัวของรีจิสทรีในไฟล์ .npmrc
ของคุณได้ (โดยพื้นฐานแล้วตอนนี้ทุกคนมีแหล่งส่วนตัวแล้ว)
# .npmrc @doppelmutzi:registry=https://gitlab.doppelmutzi.com/api/v4/projects/41/packages/npm/
มีตัวเลือกการกำหนดค่ามากมายสำหรับ npm
ทางที่ดีควรตรวจสอบในเอกสารประกอบ
คุณสามารถตั้งค่า workspaces
ของ yarn
ได้ใน package.json
(ต้องเป็นแพ็คเกจส่วนตัว)
- - "ส่วนตัว": จริง "พื้นที่ทำงาน": ["พื้นที่ทำงาน-a", "พื้นที่ทำงาน-b"] }
การกำหนดค่าเพิ่มเติมใดๆ จะอยู่ในไฟล์ .yarnrc
ตัวเลือกการกำหนดค่าทั่วไปคือการตั้ง yarn-path:
โดยบังคับให้สมาชิกในทีมแต่ละคนใช้เวอร์ชันไบนารี่ที่ระบุ yarn-path
ชี้ไปที่โฟลเดอร์ที่มีเวอร์ชัน Yarn
เฉพาะ (เช่น .yarn/releases/
) คุณสามารถติดตั้งเวอร์ชัน Yarn Classic
แบบครบวงจรได้โดยใช้คำสั่ง (classic.yarnpkg.com/en/docs/cli…)
การกำหนดค่า workspaces
ใน Yarn Berry
คล้ายกับการกำหนดค่าใน Yarn Classic
( package.json
) การกำหนดค่า Yarn Berry
ส่วนใหญ่เกิดขึ้นใน .yarnrc.yml
และมีตัวเลือกการกำหนดค่ามากมายให้เลือก
# .yarnrc.yml YarnPath: .yarn/releases/yarn-3.1.1.cjs
yarn berry
สามารถใช้วิธีการนำเข้า $> yarn plugin import <name>
เพื่อขยายปลั๊กอิน (yarnpkg.com/cli/plugin/…) คำสั่งนี้จะ ยังได้รับการอัพเดต .yarnrc.yml
# .yarnrc.yml ปลั๊กอิน: - เส้นทาง: .yarn/plugins/@yarnpkg/plugin-semver-up.cjs ข้อมูลจำเพาะ: "https://raw.githubusercontent.com/tophat/yarn-plugin-semver-up/master/bundles/%40yarnpkg/plugin-semver-up.js"
ตามที่กล่าวไว้ในส่วนประวัติเนื่องจากเหตุผลด้านความเข้ากันได้ อาจมีปัญหาบางอย่างเกี่ยวกับการขึ้นต่อกันในโหมด PnP เข้มงวด มีวิธีแก้ไขปัญหา PnP ประเภทนี้โดยทั่วไป: นโยบายการกำหนดค่าส่วนขยายแพ็คเก็ต
# .yarnrc.yml ส่วนขยายแพ็คเกจ: "สไตล์ส่วนประกอบ@*": การพึ่งพา: react-is: "*"
pnpm
ใช้กลไกการกำหนดค่าเดียวกันกับ npm
ดังนั้นคุณสามารถใช้ไฟล์ .npmrc
ได้ การกำหนดค่ารีจิสทรีส่วนตัวยังทำงานเหมือนกับการใช้ npm
สามารถรองรับโปรเจ็กต์แบบหลายแพ็คเกจได้ด้วยฟีเจอร์พื้นที่ทำงานของ pnpm ในการเริ่มต้น monorepo
คุณต้องระบุตำแหน่งของแพ็กเกจในไฟล์ pnpm-workspace.yaml
# pnpm-workspace.yaml แพ็คเกจ: - 'แพ็คเกจ/**'
(จริงๆ แล้วมีสามแนวคิดที่นี่ คลังสินค้าเดี่ยวและหลายโครงการ คลังสินค้าเดี่ยวและโครงการเดียว และคลังสินค้าหลายแห่งและหลายโครงการ)
monorepo
คือพื้นที่เก็บข้อมูลที่มีหลายโครงการ โปรเจ็กต์เหล่านี้เรียกว่า workspace
หรือแพ็คเกจ การเก็บทุกอย่างไว้ในที่เดียวแทนที่จะใช้ที่เก็บข้อมูลหลายแห่งถือเป็นกลยุทธ์การจัดระเบียบโครงการ
แน่นอนว่าสิ่งนี้ทำให้เกิดความซับซ้อนเพิ่มเติม Yarn Classic
เป็นคนแรกที่เปิดใช้งานคุณสมบัตินี้ แต่ตอนนี้ผู้จัดการแพ็คเกจรายใหญ่ทุกรายเสนอฟังก์ชันพื้นที่ทำงาน ส่วนนี้จะแสดงวิธีกำหนดค่าพื้นที่ทำงานของคุณโดยใช้ตัวจัดการแพ็คเกจที่แตกต่างกัน
ทีม npm
ได้เปิดตัวฟีเจอร์พื้นที่ทำงาน npm ที่รอคอยมานานในเวอร์ชัน 7 ประกอบด้วยคำสั่ง CLI มากมายเพื่อช่วยจัดการโปรเจ็กต์แบบหลายแพ็คเกจจากแพ็คเกจรูท คำสั่งส่วนใหญ่สามารถใช้กับตัวเลือกที่เกี่ยวข้องกับ workspace
เพื่อบอก npm
ว่าควรรันกับพื้นที่ทำงานเฉพาะ หลาย หรือทั้งหมด
# การติดตั้งการอ้างอิงทั้งหมดสำหรับพื้นที่ทำงานทั้งหมด $ npm i --พื้นที่ทำงาน #วิ่งแข่งกับแพ็คเกจเดียว การทดสอบการรัน $ npm --workspace=hooks # รันกับหลายแพ็คเกจ การทดสอบการทำงาน $ npm --workspace=hooks --workspace=utils #วิ่งสู้ทุกสิ่ง การทดสอบการรัน $ npm -- พื้นที่ทำงาน #ignore แพ็คเกจทั้งหมดที่ขาดการทดสอบ $ npm run test --workspaces --if-present
tips: เมื่อเปรียบเทียบกับตัวจัดการแพ็กเกจอื่นๆ ในปัจจุบัน npm
v8 ไม่รองรับการกรองขั้นสูงหรือการดำเนินการแบบขนานของคำสั่งที่เกี่ยวข้องกับพื้นที่ทำงานหลายคำสั่ง
ในเดือนสิงหาคม 2017 ทีม Yarn
ได้ประกาศการสนับสนุน monorepo
สำหรับฟังก์ชันพื้นที่ทำงาน ก่อนหน้านี้ ตัวจัดการแพ็คเกจสามารถใช้ได้เฉพาะในโครงการที่มีหลายแพ็คเกจด้วยซอฟต์แวร์บุคคลที่สาม เช่น Lerna การเพิ่ม Yarn
ใหม่นี้ยังปูทางให้ผู้จัดการแพ็คเกจรายอื่นใช้งานฟังก์ชันดังกล่าวได้
หากคุณสนใจ คุณสามารถดูวิธีใช้ฟังก์ชันพื้นที่ทำงานของ Yarn Classic ทั้งแบบมีและไม่มี Lerna แต่บทความนี้จะแนะนำเฉพาะคำสั่งที่จำเป็นเพื่อช่วยคุณจัดการการขึ้นต่อกันในการตั้งค่าพื้นที่ทำงาน Yarn Classic
# ติดตั้งการพึ่งพาทั้งหมด $yarn สำหรับทุกพื้นที่ทำงาน # แสดงข้อมูลพื้นที่ทำงานของแผนผังการพึ่งพา $ Yarn # เรียกใช้แพ็คเกจอื่นเพื่อเริ่มต้น $ เวิร์กสเปซเส้นด้ายที่ยอดเยี่ยม - การเริ่มต้นแพ็คเกจ # เพิ่ม Webpack ในแพ็คเกจ $ Yarn Workspace สุดยอด - เพิ่มแพ็คเกจ - D webpack # เพิ่ม React สำหรับแพ็คเกจทั้งหมด $ Yarn เพิ่ม react -W
Yarn Berry
ได้นำเสนอพื้นที่ทำงานตั้งแต่เริ่มต้น เนื่องจากการนำไปปฏิบัตินั้นสร้างขึ้นจากแนวคิดของ Yarn Classic
ในความคิดเห็นของ Reddit หัวหน้านักพัฒนาของ Yarn Berry ได้ให้ภาพรวมโดยย่อเกี่ยวกับฟีเจอร์ที่มุ่งเน้นพื้นที่ทำงาน ซึ่งรวมถึง:
Yarn Berry
ใช้โปรโตคอลจำนวนหนึ่งที่สามารถใช้ได้ใน dependencies
หรือ devDependencies
ของไฟล์ package.json
หนึ่งในนั้นคือโปรโตคอล workspace
ตรงกันข้ามกับพื้นที่ทำงานของ Yarn Classic
Yarn Berry
กำหนดไว้อย่างชัดเจนว่าการขึ้นต่อกันจะต้องเป็นหนึ่งในแพ็คเกจใน monorepo
นี้ มิฉะนั้นหากเวอร์ชันไม่ตรงกัน Yarn Berry
อาจพยายามรับเวอร์ชันจากรีจิสตรีระยะไกล
- - "การอ้างอิง": { "@doppelmutzi/hooks": "พื้นที่ทำงาน:*", "http-เซิร์ฟเวอร์": "14.0.0", - - }
ผ่านโปรโตคอล workspace
pnpm
ได้มีส่วนร่วมในโครงการ monorepo
ที่คล้ายกับ Yarn Berry
คำสั่ง pnpm
จำนวนมากยอมรับตัวเลือก --recursive (-r)
หรือ --filter ซึ่งมีประโยชน์อย่างยิ่งในบริบท monorepo
คำสั่งการกรองดั้งเดิมของมันยังเป็นส่วนเสริมที่ยอดเยี่ยมของ Lerna
#ตัดแต่งพื้นที่ทำงานทั้งหมด pnpm -r exec -- rm -rf node_modules && rm pnpm-lock.yaml # รันการทดสอบทั้งหมดสำหรับพื้นที่ทำงานทั้งหมดด้วยขอบเขต @doppelmutzi การทดสอบการทำงานแบบเรียกซ้ำ pnpm --filter @doppelmutzi/`
ประสิทธิภาพเป็นส่วนสำคัญของการตัดสินใจคัดเลือก ส่วนนี้นำเสนอเกณฑ์มาตรฐานตามโครงการขนาดเล็กและขนาดกลาง นี่คือหมายเหตุบางส่วนเกี่ยวกับโครงการตัวอย่าง:
รายการ สำหรับการประเมินและคำอธิบายโดยละเอียด โปรดดูผลลัพธ์ของโครงการ 1 (P1) และโครงการ 2 (P2)
node_modules
หรือ .pnp.cjs
node_modules
หรือ .pnp.cjs
node_modules
หรือ .pnp.cjs
ฉันใช้เครื่องมือ gnomon เพื่อวัดเวลาที่ใช้โดยการติดตั้ง ( yarn
| gnomon
) นอกจากนี้ ฉันวัดขนาดของไฟล์ที่สร้างขึ้น $ du -sh node_modules
ผลการดำเนินงานโครงการที่ 1 | |||||||
---|---|---|---|---|---|---|---|
วิธี | npm v8.1.2 | Yarn Classic v1.23.0 | pnpm v6.24.4 | Yarn Berry PnP loose v3.1.1 | Yarn Berry PnP strict v3.1.1 | Yarn Berry node_modules v3.1.1 | Yarn Berry pnpm v3.1.1 |
UC 1 | 86.63s | 108.89s | 43.58s | 31.77s | 30.13 วินาที | 56.64 | วินาที 60.91 | วินาที
UC 2 | 41.54 วินาที | 65.49 | วินาที 26.43 | วินาที 12.46 | วินาที 12.66 | วินาที 46.36 วินาที | 40.74 วินาที |
UC 3 | 23.59 วินาที | 40.35 | วินาที 20.32 | วินาที 1.61 | วินาที 1.36 | วินาที | 28.72 วินาที |
ไฟล์ 9s และขนาด | package-lock.json: 1.3M node_modules : 467M | node_modules: 397M Yarn.lock: 504K | pnpm-lock.yaml: 412K node_modules: 319M | Yarn.lock: แคช 540K: ถอดปลั๊ก 68M: 29M .pnp.cjs: 1.6M | Yarn.lock: แคช 540K: ถอดปลั๊ก 68M: 29M pnp.cjs: 1.5M | node_modules: 395M Yarn.lock: แคช 540K: 68M | node_modules: 374M Yarn.lock: แคช 540K: |
ผลลัพธ์ประสิทธิภาพ 68M สำหรับโครงการ 2 | |||||||
---|---|---|---|---|---|---|---|
วิธี | npm v8.1.2 | Yarn Classic v1.23.0 | pnpm v6.24.4 | Yarn Berry PnP loose v3.1.1 | Yarn Berry PnP strict v3.1.1 | Yarn Berry node_modules v3.1.1 | Yarn Berry pnpm v3.1.1 |
UC 1 | 34.91s | 43.26s | 15.6s | 13.92s | 6.44s | 23.62s | 20.09s |
UC 2 | 7.92s | 33.65s | 8.86s | 7.09s | 5.63s | 15.12s | 14.93s |
UC 3 | 5.09s | 15.64s | 4.73s | 0.93s | 0.79s | 8.18s | 6.02s |
ไฟล์และขนาด | แพ็คเกจล็อค .json: 684K โหนด_โมดูล: 151M | เส้นด้ายล็อค: 268K node_modules: 159M | pnpm-lock.yaml: 212K node_modules: 141M | .pnp.cjs: 1.1M .pnp.loader.mjs: 8.0K เส้นด้ายล็อค: 292K .yarn: 38M | .pnp.cjs: 1.0 M .pnp.loader.mjs: 8.0K Yarn.lock: 292K .yarn: 38M | Yarn.lock: 292K node_modules: แคช 164M: 34M | Yarn.lock: 292K node_modules: แคช 156M: |
npm
ค่อนข้างผ่อนปรนเกินไปเล็กน้อยเมื่อพูดถึงการจัดการแพ็คเกจที่ไม่ดี และพบช่องโหว่ด้านความปลอดภัยที่ส่งผลกระทบโดยตรงต่อหลายโครงการ ตัวอย่างเช่น ในเวอร์ชัน 5.7.0 เมื่อคุณรันคำสั่ง sudo npm
บนระบบปฏิบัติการ Linux คุณสามารถเปลี่ยนความเป็นเจ้าของไฟล์ระบบได้ ส่งผลให้ระบบปฏิบัติการใช้งานไม่ได้
อีกเหตุการณ์หนึ่งเกิดขึ้นในปี 2018 ที่เกี่ยวข้องกับการขโมย Bitcoins แพ็คเกจ Node.js EventStream เพิ่มการพึ่งพาที่เป็นอันตรายในเวอร์ชัน 3.3.6 แพ็คเกจที่เป็นอันตรายนี้มีวิธีการเข้ารหัสที่พยายามขโมย Bitcoins จากเครื่องของผู้พัฒนา
เพื่อช่วยแก้ไขปัญหาเหล่านี้ เวอร์ชัน npm
ใหม่จะใช้อัลกอริธึมการเข้ารหัสเพื่อตรวจสอบความสมบูรณ์ของแพ็คเกจที่คุณติดตั้ง SHA-512.
Yarn Classic
และ Yarn Berry
ใช้เช็คซัมเพื่อตรวจสอบความสมบูรณ์ของทุกแพ็คเกจตั้งแต่ต้น Yarn
ยังพยายามป้องกันคุณจากการดึงแพ็คเกจที่เป็นอันตรายที่ไม่ได้ประกาศใน package.json
: หากพบว่าไม่ตรงกัน การติดตั้งจะถูกยกเลิก
Yarn Berry
ในโหมด PnP ไม่มีปัญหาด้านความปลอดภัยของวิธี node_modules
แบบเดิม เมื่อเปรียบเทียบกับ Yarn Classic
Yarn Berry
จะปรับปรุงความปลอดภัยของการดำเนินการคำสั่ง คุณสามารถรันได้เฉพาะแพ็คเกจที่ได้รับการประกาศใน package.json
เท่านั้น คุณลักษณะความปลอดภัยนี้คล้ายกับ pnpm
ซึ่งฉันอธิบายไว้ด้านล่าง
pnpm
ยังคงใช้เช็คซัมเพื่อตรวจสอบความสมบูรณ์ของแต่ละแพ็คเกจที่ติดตั้งก่อนที่จะรันโค้ด
ตามที่เรากล่าวไว้ข้างต้น ทั้ง npm
และ Yarn Classic
มีปัญหาด้านความปลอดภัยเนื่องจากการเลื่อนระดับ pnpm
หลีกเลี่ยงสถานการณ์นี้เนื่องจากโมเดลการจัดการไม่ได้ใช้การยกระดับ แต่จะสร้างโฟลเดอร์ node_modules
ที่ซ้อนกัน ซึ่งจะช่วยลดความเสี่ยงในการเข้าถึงการพึ่งพาที่ผิดกฎหมาย ซึ่งหมายความว่ามีการประกาศการขึ้นต่อกันใน .package.json
ดังที่เราได้พูดคุยไปแล้ว สิ่งนี้มีความสำคัญอย่างยิ่งในการตั้งค่า monorepo
เนื่องจากบางครั้งอัลกอริธึมการเร่งอาจนำไปสู่การพึ่งพาแบบไม่กำหนด
npm | Yarn Classic | Yarn Berry | pnpm |
Svelte | React | Jest (พร้อม node_modules) | Vue 3 |
Preact | Angular | Storybook (พร้อม node_modules) | Browserlist |
Express.js | Ember | Babel (พร้อม node_modules) | Prisma |
Meteor | Next.js | Redux Toolkit (พร้อม node_modules) | SvelteKit |
Apollo Server | Gatsby | ||
นัท | |||
สร้างแอป React | |||
webpack-cli | |||
อารมณ์ |
มีความแตกต่างอย่างมากในหลักการของผู้จัดการแพ็คเกจที่แตกต่างกัน
pnpm
เริ่มแรกดูเหมือนว่า npm
ซึ่งการใช้ CLI ของพวกเขานั้นคล้ายคลึงกัน แต่การจัดการการพึ่งพา pnpm
แตกต่างกันมาก Yarn Classic
ยังคงเป็นที่นิยม แต่ก็ถือว่าเป็นซอฟต์แวร์ดั้งเดิมและการสนับสนุนอาจลดลงในอนาคตอันใกล้ Yarn Berry PnP
เป็นแบรนด์ใหม่ แต่ศักยภาพในการปฏิวัติโลกของผู้จัดการแพ็คเกจยังไม่ได้รับการตระหนักอีกครั้ง
ในช่วงหลายปีที่ผ่านมาผู้ใช้หลายคนถามว่าใครใช้ผู้จัดการแพ็คเกจและคนโดยรวมดูเหมือนจะสนใจเป็นพิเศษในการครบกำหนดและการยอมรับของ Yarn Berry PnP
วัตถุประสงค์ของบทความนี้คือเพื่อให้คุณมีมุมมองหลายมุมมองเพื่อตัดสินใจว่าผู้จัดการแพ็คเกจใดที่จะใช้ด้วยตัวคุณเอง ฉันอยากจะชี้ให้เห็นว่าฉันไม่แนะนำตัวจัดการแพ็คเกจเฉพาะ ขึ้นอยู่กับว่าคุณชั่งน้ำหนักข้อกำหนดที่แตกต่างกันอย่างไร - ดังนั้นคุณยังสามารถเลือกสิ่งที่คุณต้องการได้!
ที่อยู่ดั้งเดิมภาษาอังกฤษ: https://blog.logrocket.com/javascript-package-managers-compared/