Istnieją biblioteki JavaScript innych firm, które mają pewne funkcje, których chciałbym używać na serwerze Node.js. (W szczególności chcę użyć biblioteki JavaScript QuadTree, którą znalazłem). Ale te biblioteki to tylko proste .js
pliki, a nie „biblioteki Node.js”.
W związku z tym te biblioteki nie są zgodne ze exports.var_name
składnią, której Node.js oczekuje dla swoich modułów. O ile rozumiem, oznacza to, że kiedy to zrobisz, module = require('module_name');
lub module = require('./path/to/file.js');
skończysz z modułem bez publicznie dostępnych funkcji itp.
Moje pytanie brzmi zatem: „Jak załadować dowolny plik javascript do Node.js, aby móc wykorzystać jego funkcjonalność bez konieczności przepisywania go tak, aby działał exports
?”
Jestem bardzo nowy w Node.js, więc daj mi znać, jeśli jest jakaś rażąca dziura w moim zrozumieniu, jak to działa.
EDYCJA : Badam więcej rzeczy i teraz widzę, że wzorzec ładowania modułów, którego używa Node.js, jest w rzeczywistości częścią niedawno opracowanego standardu ładowania bibliotek Javascript o nazwie CommonJS . Mówi to bezpośrednio na stronie dokumentacji modułu dla Node.js , ale do tej pory to przegapiłem.
Może się okazać, że odpowiedź na moje pytanie brzmi: „Poczekaj, aż autorzy z Twojej biblioteki zajmą się pisaniem interfejsu CommonJS, albo zrób to sam”.
źródło
Odpowiedzi:
Jest znacznie lepsza metoda niż użycie
eval
:vm
moduł.Na przykład, oto mój
execfile
moduł, który ocenia skryptpath
w dowolnymcontext
lub globalnym kontekście:Można go używać w ten sposób:
Gdzie
example.js
zawiera:Dużą zaletą tej metody jest to, że masz pełną kontrolę nad zmiennymi globalnymi w wykonywanym skrypcie: możesz przekazać niestandardowe wartości globalne (via
context
), do których zostaną dodane wszystkie wartości globalne utworzone przez skryptcontext
. Debugowanie jest również łatwiejsze, ponieważ błędy składniowe i tym podobne będą zgłaszane z poprawną nazwą pliku.źródło
runInNewContext
używa kontekstu globalnego, jeślicontext
(w innych przypadkach określany jakosandbox
, w dokumentach) jest niezdefiniowany? (ten punkt nie został wyjaśniony przez żaden dokument, który znalazłem)vm
zaoferować moduł w tym przypadku?Oto, co uważam za „najlepszą” odpowiedź na tę sytuację.
Powiedzmy, że masz plik skryptu o nazwie
quadtree.js
.Powinieneś zbudować niestandardowy,
node_module
który ma taką strukturę katalogów ...Wszystko w Twoim
./node_modules/quadtree/quadtree-lib/
katalogu to pliki z biblioteki innej firmy.Wtedy twój
./node_modules/quadtree/index.js
plik po prostu załaduje tę bibliotekę z systemu plików i wykona pracę eksportu rzeczy poprawnie.Teraz możesz używać swojego
quadtree
modułu jak każdego innego modułu węzłowego ...Podoba mi się ta metoda, ponieważ nie ma potrzeby zmieniać żadnego kodu źródłowego biblioteki innej firmy - więc jest łatwiejsza w utrzymaniu. Wszystko, co musisz zrobić po aktualizacji, to spojrzeć na ich kod źródłowy i upewnić się, że nadal eksportujesz odpowiednie obiekty.
źródło
npm link
jej w aplikacji. Następnie jest obsługiwany tak, jakby był natywnym pakietem Node.js.Najprostszy sposób:
eval(require('fs').readFileSync('./path/to/file.js', 'utf8'));
To świetnie sprawdza się podczas testowania w powłoce interaktywnej.źródło
AFAIK, tak właśnie należy ładować moduły. Jednak zamiast dołączać wszystkie wyeksportowane funkcje do
exports
obiektu, możesz również przypisać jethis
(co w przeciwnym razie byłoby obiektem globalnym).Jeśli więc chcesz zachować zgodność innych bibliotek, możesz to zrobić:
lub, gdy biblioteka zewnętrzny ma już swoją własną przestrzeń nazw, na przykład
jQuery
(nie, że można użyć , że w środowisku po stronie serwera):W środowisku innym niż węzeł,
this
rozwiązywałoby się do obiektu globalnego, czyniąc go w ten sposób zmienną globalną ... którą już był. Więc to nie powinno niczego zepsuć.Edycja : James Herdman ma fajny napis o node.js dla początkujących, który również o tym wspomina.
źródło
Nie jestem pewien, czy faktycznie skorzystam z tego, ponieważ jest to raczej hakerskie rozwiązanie, ale jednym ze sposobów jest zbudowanie małego importera mini-modułów, takiego jak ten ...
W pliku
./node_modules/vanilla.js
:Jeśli chcesz skorzystać z funkcji swojej biblioteki, musisz ręcznie wybrać nazwy do wyeksportowania.
Więc dla biblioteki takiej jak plik
./lib/mylibrary.js
...Jeśli chcesz wykorzystać jego funkcjonalność w swoim kodzie Node.js ...
Nie wiem jednak, jak dobrze to wszystko zadziała w praktyce.
źródło
Udało mi się to zrobić, bardzo łatwo aktualizując ich skrypt, po prostu dodając
module.exports =
tam, gdzie było to konieczne ...Na przykład wziąłem ich plik i skopiowałem do „./libs/apprise.js”. Wtedy od czego się zaczyna
W ten sposób przypisałem funkcję
module.exports =
:W ten sposób mogę zaimportować bibliotekę do mojego kodu w następujący sposób:
I byłem gotowy. YMMV, to było z pakietem internetowym .
źródło
Prosta
include(filename)
funkcja z lepszym komunikowaniem się o błędach (stos, nazwa pliku itp.)eval
W przypadku błędów:Ale z nodejs jest nawet brudniej: musisz to określić:
W przeciwnym razie nie można używać zmiennych globalnych w plikach dołączonych do
include(...)
.źródło