ฉันจะสร้างหลายโปรเจ็กต์แชร์ไดเร็กทอรี node_modules ได้อย่างไร


94

เมื่อใดก็ตามที่ฉันสร้างโปรเจ็กต์ฉันต้องดาวน์โหลดการอ้างอิงทั้งหมดของโมดูลโหนด โดยไม่ต้องคัดลอก node_modules จะมีการแชร์ node_modules กลางในหลายโครงการหรือไม่

ดังต่อไปนี้ต้องเรียกใช้หลายคำสั่งทุกครั้ง ..

npm install gulp-usemin                                                                        
npm install gulp-wrap
npm install gulp-connect
npm install gulp-watch
npm install gulp-minify-css
npm install gulp-uglify
npm install gulp-concat
npm install gulp-less
npm install gulp-rename
npm install gulp-minify-html

3
คุณสามารถติดตั้งได้ในไดเร็กทอรีหลักทั่วไปหากมี โหนดจะเดินขึ้นไปตามไดเร็กทอรีที่ค้นหาrequireโมดูล d มิฉะนั้นไม่มีไม่ได้เป็นอย่างเป็นทางการ "กลาง" โฟลเดอร์สำหรับใช้กับnode_modules require()
Jonathan Lonowski

คุณสามารถติดตั้งแพ็คเกจเหล่านี้แบบโกลบอลได้โดยใช้แฟล็กส่วนกลาง คุณจึงไม่จำเป็นต้องเรียกใช้คำสั่งติดตั้งทุกครั้ง npm install <npm_package_name> -g
Saba Hassan

คำตอบ:


90

คุณสามารถแชร์ไดเร็กทอรี node_modules ระหว่างโปรเจ็กต์ได้อย่างแน่นอน

จากเอกสารของโหนด :

หากตัวระบุโมดูลส่งผ่านไปยัง require () ไม่ใช่โมดูลดั้งเดิมและไม่ได้ขึ้นต้นด้วย '/', '../' หรือ './' โหนดจะเริ่มต้นที่ไดเร็กทอรีหลักของโมดูลปัจจุบันและเพิ่ม / node_modules และพยายามโหลดโมดูลจากตำแหน่งนั้น

หากไม่พบที่นั่นระบบจะย้ายไปยังไดเร็กทอรีพาเรนต์และอื่น ๆ จนกว่าจะถึงรูทของระบบไฟล์

ตัวอย่างเช่นหากไฟล์ที่ '/home/ry/projects/foo.js' เรียกว่าต้องใช้ ('bar.js') โหนดจะดูในตำแหน่งต่อไปนี้ตามลำดับนี้:

/home/ry/projects/node_modules/bar.js /home/ry/node_modules/bar.js /home/node_modules/bar.js /node_modules/bar.js

ดังนั้นเพียงแค่ใส่โฟลเดอร์ node_modules ไว้ในไดเร็กทอรีโปรเจ็กต์ของคุณและใส่โมดูลที่คุณต้องการ เพียงแค่ต้องการให้เหมือนปกติ เมื่อโหนดไม่พบไดเร็กทอรี node_modules ในโฟลเดอร์โปรเจ็กต์ของคุณโหนดจะตรวจสอบโฟลเดอร์หลักโดยอัตโนมัติ ดังนั้นให้สร้างโครงสร้างไดเร็กทอรีของคุณดังนี้:

-myProjects
--node_modules
--myproject1
---sub-project
--myproject2

ดังนั้นสิ่งนี้แม้แต่การอ้างอิงของโปรเจ็กต์ย่อยของคุณก็สามารถวาดบนที่เก็บ node_modules หลักของคุณได้

ข้อเสียเปรียบอย่างหนึ่งในการทำเช่นนี้คือคุณจะต้องสร้างไฟล์ package.json ของคุณด้วยตนเอง (เว้นแต่จะมีใครรู้วิธีทำให้สิ่งนี้เป็นไปโดยอัตโนมัติด้วยคำรามหรืออะไรบางอย่าง) เมื่อคุณติดตั้งแพ็กเกจและเพิ่ม --save arg ลงในnpm installคำสั่งมันจะต่อท้ายโดยอัตโนมัติในส่วนการอ้างอิงหรือ package.json ของคุณซึ่งสะดวก


3
เหตุใดจึงไม่ยอมรับสิ่งนี้เป็นคำตอบ คำถามเพิ่มเติมสำหรับ @tpie ควรจัดโครงสร้างโครงการอย่างที่คุณแนะนำหรือไม่เราจะสร้าง package.json เพื่อติดตั้งจากที่เก็บโมดูลหลักได้อย่างไร
diehell

@diehell ดูเหมือนว่า "ทั้งหมดหรือไม่มีอะไร" หากทั้งหมดหรือการอ้างอิงอยู่ในไดเร็กทอรีหลักและไม่มีไดเร็กทอรี node_modules ใน CWD ดังนั้น npm จะตรวจสอบพาเรนต์และติดตั้งที่นั่นหากพบ หากคุณใส่โฟลเดอร์ node_modules ในไดเร็กทอรีมันจะติดตั้งที่นั่น
tpie

4
ฉันไม่เห็นว่าการแชร์ node_modules สามารถจัดการแพ็กเกจเวอร์ชันต่างๆได้อย่างไรแพ็กเกจใน node_modules ไม่ได้เป็นเวอร์ชันซึ่งแตกต่างจาก npm-cache ใน c: \ users (Windows) มีใครพบเจอหรือไม่
cyberguest

ฉันจะแก้ไขกระบวนทัศน์ของฉันได้อย่างไรเมื่อเขียนสคริปต์ npm และไฟล์ package.json
Maddocks

18

ฉันพบเคล็ดลับเพียงแค่ดูที่Symbolic Links (symlinks) บน Windows หรือ Linuxมันใช้งานได้เหมือนกับทางลัด แต่มีประสิทธิภาพมากกว่า

เพียงแค่คุณสร้างโฟลเดอร์Junctionของคุณnode_modulesได้ทุกที่ที่คุณต้องการ ทางแยกไม่ได้เป็นอะไรนอกจากทางลัดไปยังโฟลเดอร์ node_modules ดั้งเดิมของคุณ สร้างมันขึ้นมาในโฟลเดอร์โครงการของคุณที่ node_modules npm installที่เกิดขึ้นจริงจะได้รับการสร้างขึ้นถ้าใช้

เพื่อให้บรรลุสิ่งนี้คุณต้องมีnode_modulesโฟลเดอร์จริงอย่างน้อยหนึ่งโฟลเดอร์จากนั้นสร้างทางแยกไปยังโฟลเดอร์นั้นในโปรเจ็กต์อื่น ๆ

ใน Windows คุณสามารถใช้ Command Prompt หรือใช้แอปพลิเคชัน โดยใช้ Command Prompt ให้คุณนิดการควบคุมมากขึ้นโดยใช้โปรแกรมที่เป็นเรื่องง่ายที่ผมขอแนะนำให้เชื่อมโยงส่วนขยายเชลล์


1
ฉัน cd ไปยังเป้าหมาย dir รันคำสั่งนี้: mklink /d node_modules (source dir)\node_modules.
ChrisTorng

1
ทีมของฉันใช้วิธีนี้มาระยะหนึ่งแล้ว ในขณะที่ฉันดูถูกจริงๆว่าไม่มีnode_modulesในโฟลเดอร์โครงการ แต่ก็ใช้ได้ผล อย่าลืมเรียกดูnode_modulesโฟลเดอร์จริงก่อนที่จะติดตั้งอะไรใหม่: P
Andrew Craswell

วิธีนี้ดูเหมือนจะไม่ได้ผลสำหรับฉัน เมื่อฉันใช้สัญลักษณ์หรือทางแยกฉันได้รับข้อผิดพลาดต่อไปนี้กับ node-sass: การสร้างโมดูลล้มเหลว: "ข้อผิดพลาด: โมดูลไม่ได้ลงทะเบียนด้วยตนเอง" และข้อผิดพลาดมีรายละเอียดเพิ่มเติมที่ระบุไดเร็กทอรีที่มีไดเร็กทอรี node_modules "shared" ความคิดใด ๆ ?
flipcode

1
จะหลีกเลี่ยงการตัดการอ้างอิงเมื่อเรียกใช้npm installในแอป "เชื่อมต่อ" ได้อย่างไร
Qwerty

1
แต่เมื่อฉันเรียกใช้npm install <new-package>แพ็คเกจทั้งหมดที่ไม่ได้อยู่ใน package.json ของโปรเจ็กต์ปัจจุบันของคุณจะถูกลบออก
Rohit Kaushal

17

ลองใช้pnpmแทน npm

pnpm ใช้ฮาร์ดลิงก์และซิมลิงค์เพื่อบันทึกเวอร์ชันหนึ่งของโมดูลเพียงครั้งเดียวบนดิสก์

ติดตั้งด้วย:

npm install -g pnpm

ในการอัปเดตการติดตั้งที่มีอยู่ของคุณ (และไดเรกทอรีย่อย) ให้ใช้:

pnpm recursive install

8

ไดเร็กทอรีหลักควรมีลักษณะดังนี้

node_modules
Project 1
Project 2
Project 3
Project 4

เพียงแค่เปิดไฟล์ Project 1/.angular-cli.json

เปลี่ยนสคีมา

"$schema": "./node_modules/@angular/cli/lib/config/schema.json",

ถึง

"$schema": "./../node_modules/@angular/cli/lib/config/schema.json"

และอย่าลืมสร้างnode_modulesโฟลเดอร์ว่างภายในไดเรกทอรีโครงการของคุณ


คุณคือฮีโร่ของฉัน ฉันใช้เวลาหนึ่งสัปดาห์กับเรื่องนี้ ขอบคุณมาก!!
Eliezer Berlin

5

จากการดูบทความบางบทความดูเหมือนว่าLerna เป็นเครื่องมือที่ดีสำหรับการจัดการหลายโครงการภายในไดเรกทอรีเดียว ( monorepo) สนับสนุนการแชร์โมดูลโดยไม่ต้องทำซ้ำแพ็คเกจทั้งหมดในทุกโฟลเดอร์และคำสั่งเพื่อติดตั้งในหลายโครงการ

นอกจากนี้pnpmยังเป็นเครื่องมือที่ใช้งานง่ายและมีประสิทธิภาพซึ่งจะไม่ทำซ้ำโมดูลที่ติดตั้งไว้สำหรับโครงการอื่น


0

สมมติว่าการมี node_modules เดียวควรมีแพ็คเกจทั้งหมดสำหรับแอปพลิเคชันทั้งหมด ดังนั้นแอปของคุณจะแชร์รายการ package.json ที่ไม่ซ้ำกันส่วนใหญ่ (ควรเปลี่ยนชื่อเท่านั้น)

ความคิดของฉันคือการมีรูทเดียวและหลายระดับ src ด้านล่าง

root\package.json
root\node_modules
root\\..
root\app1\src\\..
root\app2\src\\..

ปัญหาเดียวที่คุณอาจประสบคือการสำรองข้อมูล json (หรือ tsconfig) สำหรับแอปใด ๆ และเรียกคืนเมื่อคุณทำงานหรือตั้งค่าสคริปต์เริ่มต้นเพื่อให้บริการแอปใด ๆ


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.