Chciałbym wymagać moich plików zawsze od katalogu głównego mojego projektu, a nie od bieżącego modułu.
Na przykład, jeśli spojrzysz na https://github.com/visionmedia/express/blob/2820f2227de0229c5d7f28009aa432f9f3a7b5f9/examples/downloads/app.js wiersz 6 zobaczysz
express = require('../../')
To naprawdę złe IMO. Wyobraź sobie, że chciałbym umieścić wszystkie moje przykłady bliżej źródła tylko o jeden poziom. Byłoby to niemożliwe, ponieważ musiałbym aktualizować ponad 30 przykładów i wiele razy w każdym z nich. Do tego:
express = require('../')
Moim rozwiązaniem byłoby mieć specjalny przypadek oparty na katalogu głównym: jeśli ciąg zaczyna się od $, to jest względny w stosunku do folderu głównego projektu.
Jakakolwiek pomoc się przyda, dzięki
Aktualizacja 2
Teraz używam wymaganego.js, który pozwala pisać w jeden sposób i działa zarówno na kliencie, jak i na serwerze. Require.js pozwala także tworzyć niestandardowe ścieżki.
Aktualizacja 3
Teraz przeniosłem się na webpack + gulp i korzystam z rozszerzonego wymagania do obsługi modułów po stronie serwera. Zobacz tutaj uzasadnienie: http://hackhat.com/p/110/module-loader-webpack-vs-requirejs-vs-browserify/
Odpowiedzi:
A co z:
Wymaga pliku tak, jakby był wymagany z głównego pliku js, więc działa całkiem dobrze, dopóki główny plik js znajduje się w katalogu głównym projektu ... i to doceniam.
źródło
W Podręczniku Browserify znajduje się naprawdę interesująca sekcja :
źródło
node_modules
folderze jest to, że utrudnia to nuke (rm -rf node_modules
) foldergit clean
składni, zawsze możeszrm -rf node_modules && git checkout node_modules
- upewnij się, żegit stash
w przypadku jakichkolwiek zmian wnode_modules
podkatalogach.Lubię utworzyć nowy
node_modules
folder dla wspólnego kodu, a następnie pozwolić, aby węzeł i wymagał robienia tego, co robi najlepiej.na przykład:
Na przykład, jeśli jesteś w środku
car/index.js
, możeszrequire('helper')
i węzeł go znajdzie!Jak działają moduły_węzła
Węzeł ma sprytny algorytm rozwiązywania modułów, który jest unikalny wśród konkurencyjnych platform.
Jeśli
require('./foo.js')
z/beep/boop/bar.js
, węzeł będzie szukał./foo.js
w/beep/boop/foo.js
. Ścieżki zaczynające się od./
lub../
zawsze są lokalne dla pliku, który wywołujerequire()
.Jeśli jednak potrzebujesz nie względnej nazwy, takiej jak
require('xyz')
from/beep/boop/foo.js
, węzeł przeszukuje te ścieżki w kolejności, zatrzymując się przy pierwszym dopasowaniu i zgłaszając błąd, jeśli nic nie zostanie znalezione:Dla każdego
xyz
istniejącego katalogu węzeł najpierw szuka znaku,xyz/package.json
aby sprawdzić, czy"main"
pole istnieje. Te"main"
określa, który plik pola powinno przejąć Jeślirequire()
ścieżka katalogu.Na przykład jeśli
/beep/node_modules/xyz
jest pierwszym dopasowaniem i/beep/node_modules/xyz/package.json
ma:wówczas eksport z
/beep/node_modules/xyz/lib/abc.js
zostanie zwrócony przezrequire('xyz')
.Jeśli nie
package.json
ma"main"
pola lub nie ma go ,index.js
przyjmuje się:źródło
Wielkie zdjęcie
Wydaje się „naprawdę zły”, ale daj mu czas. To jest naprawdę dobre. Te wyraźne
require()
zapewniają całkowitą przejrzystość i łatwość zrozumienia, która jest jak powiew świeżego powietrza podczas cyklu życia projektu.Pomyśl o tym w ten sposób: czytasz przykład, zanurzając palce w Node.js i zdecydowałeś, że to „naprawdę zły IMO”. Jesteś drugim przywódcą społeczności Node.js, który zapisał więcej godzin na pisanie i utrzymywanie aplikacji Node.js niż ktokolwiek inny. Jaka jest szansa, że autor popełnił taki debiutant? (I zgadzam się, z mojego środowiska Ruby i Python, na początku wydaje się to katastrofą.)
Wokół Node.js. jest dużo szumu i przeciwdziałania. Ale kiedy opadnie kurz, uznamy, że wyraźne moduły i pakiety „najpierw lokalne” były głównym motorem adopcji.
Wspólny przypadek
Oczywiście
node_modules
z bieżącego katalogu przeszukiwany jest rodzic, a następnie dziadek, pradziadek itp. Więc pakietów zainstalowano już działa w ten sposób. Zwykle możesz to zrobićrequire("express")
z dowolnego miejsca w projekcie i działa dobrze.Jeśli zauważysz, że ładujesz wspólne pliki z katalogu głównego projektu (być może dlatego, że są to wspólne funkcje narzędziowe), to jest duża wskazówka, że nadszedł czas, aby stworzyć pakiet. Pakiety są bardzo proste: przenieś swoje pliki
node_modules/
i umieśćpackage.json
tam. Voila! Wszystko w tej przestrzeni nazw jest dostępne z całego projektu. Pakiety to właściwy sposób na przeniesienie kodu do globalnej przestrzeni nazw.Inne obejścia
Ja osobiście nie używam tych technik, ale one odpowiadają na twoje pytanie i oczywiście znasz swoją sytuację lepiej niż ja.
Możesz ustawić
$NODE_PATH
na katalog główny projektu. Ten katalog zostanie przeszukany, gdy Tyrequire()
.Następnie możesz pójść na kompromis i wymagać wspólnego, lokalnego pliku ze wszystkich swoich przykładów. Ten wspólny plik po prostu ponownie eksportuje prawdziwy plik z katalogu dziadków.
przykłady / pliki do pobrania / app.js (i wiele innych podobnych)
przykłady / pliki do pobrania / express.js
Teraz, gdy przenosisz te pliki, najgorszym przypadkiem jest naprawienie modułu z jedną podkładką dystansową .
źródło
Spójrz na node-rfr .
To takie proste:
źródło
Jeśli używasz przędzy zamiast npm , możesz użyć obszarów roboczych .
Powiedzmy, że mam folder,
services
którego chciałbym łatwiej wymagać:Aby utworzyć obszar roboczy Przędza, utwórz
package.json
plik wservices folder
:W głównym pakiecie.json dodaj:
Uruchom
yarn install
z katalogu głównego projektu.Następnie w dowolnym miejscu kodu możesz:
zamiast czegoś takiego:
źródło
IMHO, najprostszym sposobem jest zdefiniowanie własnej funkcji jako części
GLOBAL
obiektu. UtwórzprojRequire.js
w katalogu głównym swojego projektu z następującą zawartością:W głównym pliku przed wprowadzeniem
require
dowolnego modułu specyficznego dla projektu:Potem działa dla mnie:
@Totty, wymyśliłem inne rozwiązanie, które może działać w przypadku opisanym w komentarzach. Opis będzie
tl;dr
, więc lepiej pokażę zdjęcie ze strukturą mojego projektu testowego .źródło
prj/some
odprj/other
(właśnie przetestowanerequire('prj/some'
). Wszystkie wspólne moduły aplikacji mogą się tam znaleźć (np. Warstwa bazy danych). Nie zrobi różnicy, gdzie jest, powiedzmy, twójlib
. Spróbuj sprawdzić, czy pasuje.Używam
process.cwd()
w swoich projektach. Na przykład:Warto zauważyć, że doprowadzi to do
require
powstania absolutnej ścieżki, chociaż nie mam jeszcze z tym problemów.źródło
Jest to dobre omówienie tego problemu tutaj .
Zetknąłem się z tym samym problemem architektonicznym: chciałem zapewnić mojej aplikacji więcej organizacji i wewnętrznych przestrzeni nazw, bez:
Ostatecznie zdecydowałem się uporządkować kod przy użyciu konwencji nazewnictwa plików, a nie katalogów. Struktura wyglądałaby mniej więcej tak:
Następnie w kodzie:
Lub tylko
a zależności zewnętrzne są dostępne jak zwykle z node_modules:
W ten sposób cały kod aplikacji jest hierarchicznie zorganizowany w moduły i dostępny dla wszystkich innych kodów względem katalogu głównego aplikacji.
Główną wadą jest oczywiście to, że w przeglądarce plików nie można rozwinąć / zwinąć drzewa, tak jakby było ono faktycznie zorganizowane w katalogach. Ale podoba mi się to, że jest bardzo jasne, skąd pochodzi cały kod i nie używa żadnej „magii”.
źródło
../x/x
co jest już czytelne.Zakładając, że katalog główny projektu jest bieżącym katalogiem roboczym, powinno to działać:
źródło
config = require('./config.js');
jest również ważny.Wypróbowałem wiele z tych rozwiązań. Skończyło się na dodaniu tego na górze mojego głównego pliku (np. Index.js):
Dodaje to katalog główny projektu do NODE_PATH, gdy skrypt jest ładowany. Pozwala mi to wymagać dowolnego pliku w moim projekcie, odwołując się do jego ścieżki względnej z katalogu głównego projektu, np
var User = require('models/user')
. To rozwiązanie powinno działać tak długo, jak długo uruchamiasz główny skrypt w katalogu głównym projektu, zanim uruchomisz cokolwiek innego w swoim projekcie.źródło
Niektóre odpowiedzi mówią, że najlepszym sposobem jest dodanie kodu do modułu node_module jako pakietu, zgadzam się i jest to prawdopodobnie najlepszy sposób na utratę
../../../
wymaganego, ale żadna z nich tak naprawdę nie pozwala.od wersji
2.0.0
możesz zainstalować pakiet z plików lokalnych, co oznacza, że możesz utworzyć folder w swoim katalogu głównym ze wszystkimi żądanymi pakietami,więc w package.json możesz dodać
modules
(lubfoo
ibar
) jako pakiet bez publikowania lub korzystania z zewnętrznego serwera w następujący sposób:Następnie
npm install
możesz uzyskać dostęp do kodu za pomocąvar foo = require("foo")
, podobnie jak w przypadku wszystkich innych pakietów.więcej informacji można znaleźć tutaj:
https://docs.npmjs.com/files/package.json#local-paths
a tutaj jak stworzyć pakiet:
https://docs.npmjs.com/getting-started/creating-node-modules
źródło
Możesz użyć modułu, który stworzyłem, Undot . To nic zaawansowanego, tylko pomocnik, dzięki czemu możesz z łatwością uniknąć tych piekielnych kropek.
Przykład:
źródło
Możesz zdefiniować coś takiego w pliku app.js:
a następnie za każdym razem, gdy chcesz wymagać czegoś od katalogu głównego, bez względu na to, gdzie jesteś, po prostu użyj wymagaFragRoot zamiast wymagania waniliowego. Jak dotąd działa dla mnie całkiem dobrze.
źródło
requireFromRoot = ((root) => (resource) => require(`${root}/${resource}`))(__dirname);
. Podoba Ci się rozwiązanie, ale czy naprawdę musisz tak powiązać __dirname?require
działa ta funkcja?Oto faktyczny sposób, w jaki działam przez ponad 6 miesięcy. Używam folderu o nazwie node_modules jako mojego folderu głównego w projekcie, w ten sposób zawsze będzie szukał tego folderu z dowolnego miejsca, które nazywam bezwzględnym wymaganiem:
Jest to bardziej przydatne, gdy jesteś zagnieżdżony w folderach, a zmiana lokalizacji pliku jest znacznie mniejsza, jeśli jest ustawiona w sposób bezwzględny. Używam tylko 2 względne wymagania w całej mojej aplikacji .
źródło
node_modules
w/src
i pozostawić/node_modules
do sprzedawców, aby przechowywać rzeczy rozdzielić. Mam więc/src/node_modules
kod lokalny i/node_modules
dostawców.NODE_PATH
zmiennej środowiskowejImho najłatwiejszym sposobem na osiągnięcie tego jest utworzenie symbolicznego linku przy uruchamianiu aplikacji w
node_modules/app
(lub jakkolwiek to nazwiesz), który wskazuje../app
. Następnie możesz po prostu zadzwonićrequire("app/my/module")
. Łącza symboliczne są dostępne na wszystkich głównych platformach.Jednak nadal powinieneś podzielić swoje rzeczy na mniejsze, łatwe do utrzymania moduły, które są instalowane przez npm. Możesz również zainstalować swoje prywatne moduły za pomocą git-url, więc nie ma powodu, aby mieć jeden, monolityczny katalog aplikacji.
źródło
W swoim projekcie możesz zmodyfikować dowolny plik .js używany w katalogu głównym i dodać jego ścieżkę do właściwości
process.env
zmiennej. Na przykład:Następnie możesz uzyskać dostęp do nieruchomości wszędzie:
źródło
Inna odpowiedź:
Wyobraź sobie tę strukturę folderów:
testy
Następnie w pliku test.js musisz wymagać plików takich jak ten:
i w main.js :
Teraz możesz w tym celu używać babel i babel-plugin-module-resolver . plik babelrc do skonfigurowania 2 folderów głównych:
Teraz możesz wymagać plików w ten sam sposób w testach i src :
a jeśli chcesz użyć składni modułu es6 :
następnie importujesz pliki w testach i src w następujący sposób:
źródło
Właśnie natknąłem się na ten artykuł, w którym wspomniano o ścieżce modułu aplikacji . Pozwala skonfigurować bazę taką jak ta:
źródło
Czy
examples
katalog nie może zawieraćnode_modules
dowiązania symbolicznego do katalogu głównego projektu,project -> ../../
umożliwiając w ten sposób wykorzystanie przykładówrequire('project')
, chociaż nie usuwa to mapowania, ale pozwala na użycie źródłarequire('project')
zamiastrequire('../../')
.Przetestowałem to i działa z v0.6.18.
Lista
project
katalogu:Zawartość
index.js
atrybutu przypisuje wartość do właściwościexports
obiektu i wywołujeconsole.log
z komunikatem, że jest ona wymagana. Zawartośćtest.js
jestrequire('project')
.źródło
require('project.a')
? Myślę, że to może znaczyćrequire('project/a')
, chociażrequire('project').a
jest również możliwe?node_modules
katalogu w najbliższym rodzicu obu plików, a link byłby taki sam dla obu. Zobacz nodejs.org/api/…project/node_modules/project -> ../
.Jeśli ktoś szuka innego sposobu na obejście tego problemu, oto mój wkład w wysiłek:
Podstawowy pomysł: tworzysz plik JSON w katalogu głównym projektu, który mapuje ścieżki plików na nazwy skrócone (lub użyj use-automapper, aby to zrobić za Ciebie). Następnie możesz poprosić o swoje pliki / moduły, używając tych nazw. Tak jak:
Więc to jest to.
źródło
W tym celu lubię wykorzystywać sposób, w jaki węzeł ładuje się z katalogu node_module.
Jeśli ktoś spróbuje załadować moduł „rzecz”, zrobiłby coś takiego
Węzeł następnie wyszuka katalog „thing” w katalogu „node_module”.
Ponieważ moduł node_modele zwykle znajduje się u podstaw projektu, możemy wykorzystać tę spójność. (Jeśli moduł_węzła nie jest u nasady, masz inne samozapalne bóle głowy, z którymi musisz sobie poradzić.)
Jeśli wejdziemy do katalogu, a następnie wycofamy się z niego, możemy uzyskać spójną ścieżkę do katalogu głównego projektu węzła.
Następnie, jeśli chcemy uzyskać dostęp do katalogu / happy, zrobilibyśmy to.
Chociaż jest to dość zuchwałe, czuję jednak, że jeśli zmieni się funkcjonalność sposobu wczytywania modułów node_moduł, będą większe problemy do rozwiązania. To zachowanie powinno pozostać spójne.
Aby to wyjaśnić, robię to, ponieważ nazwa modułu nie ma znaczenia.
Ostatnio użyłem go do angular2. Chcę załadować usługę z katalogu głównego.
źródło
src/app/my.service
, można również skonfigurować VSC do korzystania z importu nie względnego dla plików maszynopisu.Napisałem ten mały pakiet, który pozwala wymagać pakietów według ścieżki względnej z katalogu głównego projektu, bez wprowadzania żadnych zmiennych globalnych lub nadpisywania domyślnych wartości węzłów
https://github.com/Gaafar/pkg-require
Działa to w ten sposób
źródło
Po prostu chcą śledzić na wielkim odpowiedź od Paolo Moretti i Browserify. Jeśli używasz transpilatora (np. Babel, maszynopis) i masz osobne foldery na kod źródłowy i transpilowany, takie jak
src/
idist/
, możesz użyć różnych rozwiązań, takich jaknode_modules
Dzięki następującej strukturze katalogów:
możesz następnie pozwolić babel itp. na przeniesienie
src
katalogu dodist
katalogu.dowiązanie symboliczne
Za pomocą dowiązania symbolicznego możemy pozbyć się niektórych poziomów zagnieżdżania:
Zastrzeżenie z babel --copy-Files
--copy-files
Flagababel
nie zajmuje się dowiązania dobrze. Może nawigować do..
dowiązania symbolicznego i odruchowo widzieć nieskończone pliki. Obejściem tego problemu jest użycie następującej struktury katalogów:W ten sposób kod pod
src
nadal będzieapp
rozstrzyganysrc
, podczas gdy babel nie będzie już widział dowiązań symbolicznych.źródło
Szukałem dokładnie takiej samej prostoty wymagającej plików z dowolnego poziomu i znalazłem alias modułu .
Wystarczy zainstalować:
Otwórz plik package.json, tutaj możesz dodać aliasy do swoich ścieżek, np
I użyj swoich aliasów, po prostu:
źródło
stworzyłem moduł węzła o nazwie „rekiure”
pozwala to wymagać bez użycia ścieżek względnych
jest bardzo łatwy w użyciu
źródło
Za chwilę wypróbujemy nowy sposób rozwiązania tego problemu.
Biorąc przykłady z innych znanych projektów, takich jak spring i guice, zdefiniujemy obiekt „kontekstowy”, który będzie zawierał całą instrukcję „wymaganą”.
Ten obiekt zostanie następnie przekazany do wszystkich innych modułów do użycia.
Na przykład
Wymaga to od nas napisania każdego modułu jako funkcji, która odbiera opcje, co i tak jest dla nas najlepszą praktyką.
a wtedy odniesiesz się do kontekstu zamiast wymagać czegoś.
var module1Ref = context.moduel1;
Jeśli chcesz, możesz łatwo napisać pętlę, aby wykonać wymagane instrukcje
Powinno to ułatwić życie, gdy chcesz wyśmiewać (testy), a także rozwiązać swój problem po drodze, jednocześnie czyniąc kod wielokrotnego użytku jako pakiet.
Możesz także ponownie użyć kodu inicjalizacji kontekstu, oddzielając od niego deklarację bean. na przykład twój
main.js
plik może tak wyglądaćTa metoda ma również zastosowanie do bibliotek zewnętrznych, nie trzeba sztywno kodować ich nazw za każdym razem, gdy ich potrzebujemy - będzie to jednak wymagać specjalnego traktowania, ponieważ ich eksport nie jest funkcjami, które oczekują kontekstu.
Później możemy również zdefiniować komponenty bean jako funkcje - co pozwoli nam na
require
różne moduły w zależności od środowiska - ale poza zakresem tego wątku.źródło
Miałem problem z tym samym problemem, więc napisałem pakiet o nazwie include .
Uwzględnij uchwyty określające folder główny projektu poprzez zlokalizowanie pliku package.json, a następnie przekazuje podany argument ścieżki do rodzimej metody wymagania () bez całego bałaganu ścieżki względnej. Wyobrażam sobie, że nie jest to zamiennik funkcji requ (), ale narzędzie do wymagania obsługi plików lub bibliotek spakowanych / innych firm. Coś jak
Mam nadzieję, że to może być przydatne.
źródło
Jeśli plik js punktu wejścia aplikacji (tj. Ten, na którym faktycznie uruchamiasz „węzeł”) znajduje się w katalogu głównym projektu, możesz to zrobić naprawdę łatwo za pomocą modułu npm rootpath . Po prostu zainstaluj go przez
... następnie na samej górze pliku js punktu wejścia dodaj:
Od tego momentu wszystkie wymagane wywołania są teraz względne względem katalogu głównego projektu - np.
require('../../../config/debugging/log');
Staje sięrequire('config/debugging/log');
(gdzie folder konfiguracji znajduje się w katalogu głównym projektu).źródło
W prostych wierszach możesz wywołać własny folder jako moduł:
Do tego potrzebujemy: moduł globalny i moduł ścieżki aplikacji
tutaj „App-module-path” jest modułem, umożliwia dodanie dodatkowych katalogów do ścieżki wyszukiwania modułu Node.js. A „global” oznacza, że wszystko, co dołączysz do tego obiektu, będzie dostępne wszędzie w Twojej aplikacji.
Teraz spójrz na ten fragment:
__nazwa_katalogu jest bieżącym katalogiem uruchomionym węzła. Możesz tutaj podać własną ścieżkę, aby wyszukać ścieżkę modułu.
źródło