วิธีติดตั้งแพ็กเกจหลายเวอร์ชันโดยใช้ npm


101

เนื่องจากhttps://github.com/npm/npm/issues/2943 npm จะไม่รองรับความสามารถในการใช้นามแฝงแพ็คเกจและติดตั้งแพ็กเกจเดียวกันหลายเวอร์ชัน

วิธีแก้ปัญหาที่โพสต์ในปัญหา github อาจใช้ได้กับโมดูล pure-JS แต่เมื่อ npm กลายเป็นมาตรฐานสำหรับการจัดการแพ็คเกจส่วนหน้าตอนนี้แพ็กเกจจะรวมเนื้อหาต่างๆเช่น CSS

มีวิธีแก้ปัญหาในการติดตั้งแพ็กเกจเดียวกันหลายเวอร์ชันหรือไม่

แนวคิดที่ดีที่สุดที่ฉันคิดขึ้นมาคือการ "โคลน" แพ็กเกจและเผยแพร่โดยใช้ชื่อที่แตกต่างกันเล็กน้อย

ตัวอย่างเช่นถ้าคุณต้องการหลายรุ่นของjqueryคุณอาจจะเป็นเพียงแค่การเผยแพร่แพคเกจที่เรียกว่าjquery-alias1, jquery-alias2, jquery-alias3ฯลฯ package.jsonและจากนั้นตั้งค่าที่เหมาะสมในรุ่นของคุณ

หรือคุณอาจจะตั้งชื่อแพคเกจตามจำนวนรุ่นของพวกเขาเช่นjquery-1.11.x, jquery-2.1.xฯลฯ ..

ทั้งสองวิธีนี้ดูเหมือนจะเลอะเทอะ มีตัวที่ดีกว่านี้ไหม?


ไม่ได้ Bower มาตรฐานในการบริหารจัดการแพคเกจส่วนหน้าซึ่งสามารถทำได้
laggingreflex

ใช่ bower ดูเหมือนจะเป็นทางเลือกที่นี่ มันแย่เกินไปที่ดูเหมือนจะไม่มีโซลูชัน npm เนื่องจากการแนะนำระบบการจัดการแพ็คเกจอื่นให้กับทีมขนาดใหญ่อาจเป็นเรื่องยาก โดยเฉพาะอย่างยิ่งถ้าคุณได้ตั้งค่าโครงสร้างพื้นฐานเพื่อรองรับ npm แล้ว (เช่นเซิร์ฟเวอร์รีจิสตรี npm ส่วนตัว)
ทำเครื่องหมายที่

คำตอบ:


104

ตั้งแต่npm v6.9.0 ตอนนี้ npm รองรับชื่อแทนแพ็กเกจ มันใช้ไวยากรณ์เดียวกันเป็นใช้เส้นด้าย:

npm install jquery2@npm:jquery@2
npm install jquery3@npm:jquery@3

สิ่งนี้เพิ่มสิ่งต่อไปนี้ให้กับpackage.json:

"dependencies": {
   "jquery2": "npm:jquery@^2.2.4",
   "jquery3": "npm:jquery@^3.4.1"
}

นอกจากนี้ยังสามารถติดตั้งได้โดยตรงจาก GitHub ด้วยไวยากรณ์นี้ ตัวอย่างเช่นหากคุณต้องการติดตั้งทั้งเวอร์ชันรีจิสทรี npm และ GitHub fork ของแพ็กเกจfoobar:

npm install foobar
npm install foobar-fork@github:username/foobar

1
เส้นด้ายยังรองรับการใช้นามแฝงแพ็คเกจ
Greg K

สวัสดีฉันได้ลองทำตามขั้นตอนเหล่านี้แล้วเพื่อติดตั้งแพ็คเกจ 2 คือ: "react-native-track-player": "1.1.4" และ "react-native-track-player": "1.1.8" ทำงานได้ดีบน iOS แต่บน Android จะแสดงข้อผิดพลาดว่า "MusicManager $ 1 ถูกกำหนดหลายครั้ง" ฉันจะป้องกันไม่ให้ Android สร้าง 1.1.8 ได้อย่างไร
EmBeCoRau

เนื่องจากมีข้อขัดแย้งบางอย่างในไลบรารีฉันจึงต้องใช้ 1.1.8 บน iOS และ 1.1.4 บน Android
EmBeCoRau

ไม่ได้ผลสำหรับฉันในฐานะนามแฝงของการพึ่งพาซึ่งแตกต่างจากสิ่งที่กำลังมองหานั่นคือกำลังมองหา eslintแต่ไม่รู้ว่าตอนนี้ชื่อeslint6
Crimbo

75

ฉันต้องการโพสต์ที่นี่สำหรับทุกคนเช่นฉันที่ใช้Yarnและมาที่นี่ เป็นการแทนที่แบบดรอปอินมากหรือน้อยสำหรับ NPM ที่รองรับนามแฝงนอกกรอบ:

yarn add material-ui@latest
yarn add material-ui-next@npm:material-ui@next
then

import FlatButton from 'material-ui/FlatButton'; // v0.x
import Button from 'material-ui-next/Button'; // v1.x

(เครดิตตัวอย่างไปที่https://github.com/callemall/material-ui/issues/7195#issuecomment-314547601 )


17
ขอบคุณ. เพียงเพื่อชี้แจงว่าสูตรทั่วไปคือ <alternative-name>@npm:<package-name>@<version>
NikosKeyz

5

ดูเหมือนว่า "JSPM" อาจเป็นเครื่องมือที่คุณกำลังมองหา JSPM สร้างขึ้นที่ด้านบนของ NPM แต่อนุญาตให้คุณดึงแพ็คเกจจากหลายแหล่ง (github, npm ฯลฯ ) ใช้ตัวโหลดโมดูลสากล System.js ที่ส่วนหน้าสำหรับการโหลดโมดูลและ "ใช้การจัดการเวอร์ชันแบบแบนเพื่อดาวน์โหลดลงในโฟลเดอร์ที่มีคำต่อท้ายเวอร์ชัน" ซึ่งง่ายต่อการให้เหตุผล

jspm.io

เมื่อคุณติดตั้งแพ็กเกจด้วย jspm คุณสามารถตั้งชื่อแพ็กเกจนั้นเป็นชื่อเฉพาะซึ่งคุณสามารถrequireใช้ในโมดูลของคุณได้ในภายหลัง

$ jspm install jquery
... (status msgs) ...
ok   Installed jquery as github:components/jquery@^2.1.4 (2.1.4)

$ jspm install jqueryOne=jquery@1.11.3
... (status msgs) ...
ok   Installed jqueryOne as github:components/jquery@1.11.3 (1.11.3)

      github:components/jquery 1.11.3 2.1.4

จากนั้นใน js ของคุณคุณสามารถทำได้ง่าย ๆrequire(jquery)และ / หรือrequire(jqueryOne)เท่าที่จำเป็นโดยให้คุณกลับไปกลับมาได้ตามความจำเป็น

สิ่งนี้จะเหมือนกันสำหรับแพ็คเกจใด ๆ ที่คุณต้องการใช้หลายเวอร์ชัน


2

นี่เป็นเรื่องยากที่จะทำอย่างหมดจดเนื่องจากวิธีการทำงานของ npm ดังนั้นฉันจะหลีกเลี่ยงการพยายามทำในการผลิต

อย่างไรก็ตามสำหรับการทดสอบการรวมและกรณีการใช้งานที่คล้ายกันฉันได้สร้างแพ็คเกจชื่อmultidepซึ่งช่วยให้คุณสามารถติดตั้งแพ็คเกจเดียวกันได้หลายเวอร์ชันและเป็นrequireแบบนั้น:

var multidepPackages = require('multidep')('test/multidep.json');

var jquery1 = multidepRequire('jquery', '1.11.3');
var jquery2 = multidepRequire('jquery', '2.1.4');

0

NPM Install Version ( https://github.com/scott113341/npm-install-version ) ก็เป็นตัวเลือกเช่นกัน โดยพื้นฐานแล้วมันทำในสิ่งที่โซลูชันอื่น ๆ ที่นี่ทำ (พูดในทางเทคนิค) แต่ค่อนข้างตรงไปตรงมาที่จะใช้ โมดูลที่ติดตั้งด้วยหมายเลขเวอร์ชัน (พารามิเตอร์คำสั่ง @version มาตรฐานที่ใช้โดย NPM) ได้รับการติดตั้งอย่างคาดเดาได้ในโฟลเดอร์ย่อยภายใต้node_modulesด้วยชื่อนั้น คุณยังสามารถควบคุม dir ปลายทางต่อโมดูลซึ่งมีประโยชน์กับระบบการสร้าง

ข้อมูลโค้ดการใช้งานจาก GitHub Docs:

const niv = require('npm-install-version');
const benchmark = require('./some-benchmark-function.js');

niv.install('csjs@1.0.0');
// installs csjs@1.0.0 to node_modules/csjs@1.0.0/

niv.install('csjs@1.0.1');
// installs csjs@1.0.1 to node_modules/csjs@1.0.1/

const csjs_old = niv.require('csjs@1.0.0');
const csjs_new = niv.require('csjs@1.0.1');
// require the old and new versions of csjs

benchmark([csjs_old, csjs_new], 'some-test-input');
// run our fake benchmark function on the old and new versions of csjs

0

install-npm-version( https://github.com/scott-lin/install-npm-version ) ยังเป็นอีกทางเลือกหนึ่ง สามารถใช้ในบรรทัดคำสั่งหรือผ่านอินเทอร์เฟซแบบโปรแกรม - เขียนใน TypeScript สำหรับการพัฒนาที่ทันสมัย

ตัวอย่าง # 1: ติดตั้งลงในไดเร็กทอรีเวอร์ชัน (ค่าเริ่มต้น)

import inv = require('install-npm-version');

inv.Install('chalk@2.4.0');
// installs chalk@2.4.0 to node_modules/chalk@2.4.0/

inv.Install('chalk@2.4.1');
// installs chalk@2.4.1 to node_modules/chalk@2.4.1/

ตัวอย่าง # 2: ติดตั้งลงในไดเร็กทอรีที่กำหนดเอง

import inv = require('install-npm-version');

inv.Install('chalk@2.4.0', { 'Destination': 'some/path/chalk' });
// installs chalk@2.4.0 to node_modules/some/path/chalk/

ตัวอย่าง # 3: ติดตั้งด้วยเอาต์พุตมาตรฐานที่เงียบหรือมีเสียงดัง

import inv = require('install-npm-version');

inv.Install('chalk@2.4.0', { 'Verbosity': 'Silent' });
inv.Install('chalk@2.4.0', { 'Verbosity': 'Debug' });

ตัวอย่าง # 4: เขียนทับการติดตั้งที่มีอยู่

import inv = require('install-npm-version');

inv.Install('chalk@2.4.0', { 'Destination': 'mydir' });
// installs chalk@2.4.0 to node_modules/mydir/

inv.Install('chalk@2.4.1', { 'Destination': 'mydir' });
// does not install chalk@2.4.1 since node_modules/mydir/ already exists

inv.Install('chalk@2.4.1', { 'Destination': 'mydir', 'Overwrite': true });
// installs chalk@2.4.1 to node_modules/mydir/ by overwriting existing install

0

ในกรณีของฉันฉันต้องติดตั้ง create-react-app เวอร์ชันเก่ากว่าเวอร์ชันที่ฉันติดตั้งทั่วโลกเนื่องจากฉันกำลังเรียนหลักสูตรที่ต้องใช้เวอร์ชันเก่ากว่านี้สำหรับงานที่มอบหมาย

ฉันสร้างโฟลเดอร์ใหม่เพื่อให้มีเวอร์ชันเก่ากว่านี้ซีดีลงในนั้นและทำไฟล์

npm init

หลังจากตั้งค่า shell package.json นี้แล้วฉันได้ติดตั้ง create-react-app เวอร์ชันที่ต้องการ

npm install create-react-app@1.5.2

ซึ่งสร้างโฟลเดอร์ node_modules โลคัลด้วยเวอร์ชันเก่ากว่าของ create-react-app

จากนั้นฉันสร้างสคริปต์ทุบตีอย่างง่าย (create-react-app.sh) เป็นทางลัดไปยังเวอร์ชันเก่ากว่านี้และใช้ตัวแปร bash "$ @" เพื่อส่งต่ออาร์กิวเมนต์ทั้งหมด:

#!/bin/bash
{full-directory-path}/node_modules/create-react-app/index.js "$@"

ในที่สุดฉันก็ทำให้สคริปต์ทุบตีง่าย ๆ นี้สามารถเรียกใช้งานได้

chmod u+x create-react-app.sh

ดังนั้นการเรียกใช้สคริปต์ทุบตีนี้โดยตรงจะเรียกใช้แอป create-react-app เวอร์ชันเก่ากว่า:

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