jak określić moduły lokalne jako zależności pakietu npm

267

Mam aplikację, która ma zwykły zestaw zależności od modułów stron trzecich (np. „Express”) określonych w pliku package.json w zależności. Na przykład

"express"     : "3.1.1"

Chciałbym zbudować własny kod modułowo i mieć pakiet lokalnych (czyli w systemie plików, w którym aktualnie jestem) modułów zainstalowanych przez pakiet.json. Wiem, że mogę zainstalować moduł lokalny, uruchamiając:

npm install path/to/mymodule

Nie wiem jednak, jak to zrobić za pomocą struktury zależności package.json. Użycie --saveopcji w tym poleceniu polega po prostu na umieszczeniu "mymodule": "0.0.0"w pliku package.json (nie odwołuje się do lokalizacji ścieżki pliku). Jeśli następnie usunę zainstalowaną wersję z modułów node_modules i spróbuję ponownie zainstalować z pliku package.json, zakończy się ona niepowodzeniem (ponieważ szuka „mymodule” w rejestrze centralnym i nie wygląda lokalnie).

Jestem pewien, że jest to sposób na powiedzenie "dependencies": {}strukturze, że chcę ją zainstalować ze ścieżki systemu plików, ale nie wiem jak.

Czy ktoś jeszcze miał ten problem? Dzięki.

Sam Adams
źródło
1
Naprawdę dobre pytanie. Smutne, że zdajemy sobie sprawę, że nie ma funkcji równoważnej package.jsonz tym, co mamy w Gemfile.
Jarl
3
możliwy duplikat zależności lokalnej w pakiecie.json
Kelly

Odpowiedzi:

405

npm install teraz obsługuje to

npm install --save ../path/to/mymodule

Aby to działało, mymodulemusi być skonfigurowane jako moduł z własnym package.json. Zobacz Tworzenie modułów NodeJS .

Począwszy od npm 2.0 lokalne zależności są obsługiwane natywnie. Zobacz odpowiedź danilopopeye na podobne pytanie . Skopiowałem tutaj jego odpowiedź, ponieważ to pytanie zajmuje bardzo wysoką pozycję w wynikach wyszukiwania w Internecie.

Ta funkcja została zaimplementowana w wersji 2.0.0 npm. Na przykład:

{
  "name": "baz",
  "dependencies": {
    "bar": "file:../foo/bar"
  }
}

Poprawna jest również dowolna z następujących ścieżek:

../foo/bar
~/foo/bar
./foo/bar
/foo/bar

synchronizowanie aktualizacji

Po npm installskopiowaniu mymoduledo node_moduleszmiany mymoduleźródła nie będą automatycznie widoczne w projekcie zależnym.

Istnieją dwa sposoby aktualizacji projektu zależnego

  • Zaktualizuj wersję, mymodulea następnie użyjnpm update : Jak widać powyżej, package.jsonwpis „zależności” nie zawiera specyfikatora wersji, tak jak w przypadku normalnych zależności. Zamiast tego, dla lokalnych zależności, npm updatepo prostu próbuje się upewnić, że zainstalowana jest najnowsza wersja, zgodnie z określeniem mymodule's package.json. Zobacz odpowiedź chriskelly na ten konkretny problem .

  • Zainstaluj ponownie za pomocą npm install. Spowoduje to zainstalowanie cokolwiek w mymoduleźródłowej ścieżce, nawet jeśli jest ono starsze lub ma sprawdzoną alternatywną gałąź, cokolwiek.

Randy the Dev
źródło
2
To zadziałało dla mnie. (Właśnie zrobiłem lokalną ścieżkę względną, taką jak"mymodule":"file:mymoduledir"
Don Rhummy
72
npm install --save ../my-local-repo
Ivan Rave
15
I jak go wykorzystać w projekcie? Próbuję to tak nazwać import { HelloWorld } from "my-test-lib";, ale pojawia się błąd „Nie mogę znaleźć modułu”. Proszę spojrzeć na stackoverflow.com/questions/46818083/...
Vitalii Vasylenko
6
@LucioMollinedo, czy możesz udostępnić składnię tego, jak zaimportowałeś moduł lokalny? Podobnie jak w przypadku Vitallii, pojawia się błąd „Nie mogę dobrze modułu” zimport { HelloWorld } from "my-test-lib";
Stan James
7
Nie działa to tak samo jak odwoływanie się do pakietu, ponieważ zależności nie zostaną zainstalowane w projekcie
Glass Cannon
44

Zobacz: Lokalna zależność w pakiecie.json

Wygląda na to, że odpowiedź brzmi npm link: https://docs.npmjs.com/cli/link

jasoncrawford
źródło
5
faktycznie npm link utworzy tylko dowiązania symboliczne i nie zmodyfikuje pliku package.json w celu dodania lokalnej zależności
Sebastien H.,
1
Ale jeśli nie, to w symlinkjaki sposób projekt nadrzędny będzie wiedział, jak odbudować, gdy zakończy się budowanie zależności?
Jamie Hutber
11

W końcu nie mogłem znaleźć zgrabnego sposobu, więc wybrałem katalog o nazwie, local_modulesa następnie dodałem ten skrypt bashscript do pliku package.json w skryptach-> preinstalacji

#!/bin/sh
for i in $(find ./local_modules -type d -maxdepth 1) ; do
    packageJson="${i}/package.json"
    if [ -f "${packageJson}" ]; then
        echo "installing ${i}..."
        npm install "${i}"
    fi
done
Sam Adams
źródło
5

Po wielu problemach z npm linkpoleceniem (sugerowane rozwiązanie do tworzenia lokalnych modułów bez publikowania ich w rejestrze lub utrzymywania osobnej kopii w folderze node_modules), zbudowałem mały moduł npm, aby pomóc w rozwiązaniu tego problemu.

Poprawka wymaga dwóch łatwych kroków .

Pierwszy:

npm install lib-manager --save-dev

Po drugie, dodaj to do package.json:

{  
  "name": "yourModuleName",  
  // ...
  "scripts": {
    "postinstall": "./node_modules/.bin/local-link"
  }
}

Więcej szczegółów na https://www.npmjs.com/package/lib-manager . Mam nadzieję, że to komuś pomoże.

Anurag Dutta
źródło
0

Jeśli można po prostu opublikować moduły preinstalowane w module node_modules wraz z innymi plikami, możesz to zrobić w następujący sposób:

// ./node_modules/foo/package.json
{ 
  "name":"foo",
  "version":"0.0.1",
  "main":"index.js"
}

// ./package.json
...
"dependencies": {
  "foo":"0.0.1",
  "bar":"*"
}

// ./app.js
var foo = require('foo');

Możesz także zapisać swój moduł na git i powiedzieć swojemu pakietowi macierzystemu.json, aby zainstalował zależność z git: https://npmjs.org/doc/json.html#Git-URLs-as-Dependencies

Platon
źródło
5
Niestety wymagałoby to modułów_węzła, aby moje moduły lokalne i moduły stron trzecich / wnoszone zostały zainstalowane z rejestru (np. Connect) w tym samym katalogu. Oprócz tego, że jest mylący z punktu widzenia Git / VCS (tj. Musiałby zignorować wszystko w module_węzła oprócz tych, które utworzyłem), jest to również zła praktyka (te, które napisałem i nie opublikowałem, powinny być oddzielone od tych, które inni napisali i opublikowali ).
Sam Adams,
Gdy dodam moduł lokalny, a następnie dokonam zmian, nie są one widoczne w mojej głównej aplikacji. Dlaczego tak jest?
Mark Tyers