2012-05-11 17 views
17

Może to pytanie jest trochę głupie, ale czy można załadować wiele plików .js za pomocą jednej instrukcji wymagającej? tak:Czy mogę załadować wiele plików za pomocą jednej instrukcji wymagającej?

var mylib = require('./lib/mylibfiles'); 

i zastosowanie:

mylib.foo(); //return "hello from one" 

mylib.bar(): //return "hello from two" 

A w mylibfiles folder będzie miał dwa pliki:

One.js

exports.foo= function(){return "hello from one";} 

Two.js

exports.bar= function(){return "hello from two";} 

Myślałem, aby umieścić package.json w folderze, który mówi, aby załadować wszystkie pliki, ale nie wiem jak. Inne podejście, o którym myślałem, to mieć index.js, który eksportuje wszystko ponownie, ale będę duplikować pracę.

Dzięki!

P.D: Pracuję z nodejs v0.611 na windows 7 ekspres

Odpowiedz

28

Przede wszystkim za pomocą require niczego nie powielać. Ładuje moduł i to jest buforuje to, więc wywołanie require ponownie dostanie go z pamięci (w ten sposób można modyfikować moduł w locie bez interakcji z jego kodu źródłowego - jest to czasami pożądane, na przykład, gdy chcesz przechowywać połączenie db wewnątrz moduł).

Również package.json nie ładuje niczego i nie wchodzi w interakcję z aplikacją. Jest używany tylko dla npm.

Teraz nie można wymagać wielu modułów jednocześnie. Na przykład co się stanie, jeśli zarówno One.js i mają zdefiniowaną funkcję o tej samej nazwie? Jest więcej problemów.

Ale co można zrobić, to napisać dodatkowy plik, powiedzmy modules.js o następującej treści

module.exports = { 
    one : require('./one.js'), 
    two : require('./two.js'), 
    /* some other modules you want */ 
} 

a następnie można po prostu użyć

var modules = require('./modules.js'); 
modules.one.foo(); 
modules.two.bar(); 
+1

Dzięki za pomocy, chodzi o to, że próbuję mieć pewne metody jako wewnętrzne i nie chcę, aby te funkcje mogły być dostępne przez moduł, który używa w twoim przykładzie modules.js. Myślę, że w twoim przykładzie mogę również zrobić "var one = require (./ one.js); i uzyskać te same funkcje co' one.js', czy tak jest? – nico144

+1

Korekta: Node.js faktycznie odczytuje plik 'main' pliku package.json' jako część procesu' require'. To jedyna rzecz, którą Node czyta, pozostałe informacje są dla 'npm'. – RyanZim

2

Tak, można wymagać folder jako moduł, zgodnie z node docs. Powiedzmy, że chcesz wymagać() folderu o nazwie ./mypack/.

Wewnątrz ./mypack/, utwórz plik package.json z name folderu i main plik JavaScript o tej samej nazwie, wewnątrz katalogu ./lib/.

{ 
    "name" : "mypack", 
    "main" : "./lib/mypack.js" 
} 

Teraz można użyć require('./mypack') i węzeł będzie ładować ./mypack/lib/mypack.js.

Jeśli jednak nie zostanie dołączony ten plik package.json, może on nadal działać.Bez pliku, węzeł spróbuje załadować ./mypack/index.js, lub jeśli go tam nie ma, ./mypack/index.node.

Rozumiem, że może to być korzystne, jeśli podzieliłeś program na wiele plików javascript, ale nie chcesz ich konkatenować w celu wdrożenia.

+0

dla jasności, nie można wymagać folderu jako modułu i ładować wszystkie pliki javascript w tym katalogu. dobrze? – Michael

+0

@ Michael poprawne. będzie ładował tylko wartość 'main' w katalogu głównym' package.json' lub, jeśli nie ma, root 'index.js' – chharvey

+0

@Michael - Dynamiczne ładowanie całego katalogu plików kodu ma ten sam problem w wirtualnie każdy język: w jakiej kolejności należy je załadować? Alfabetyczny? Następnie dostajesz dziwne wykrzykniki, w których umieszczasz sztuczne przedrostki w nazwach plików, aby wpłynąć na kolejność. – xyz

0

Mam fragment kodu, który wymaga więcej niż jednego modułu, ale nie grupuje ich razem, jak sugeruje Twój post. Jednak można to pokonać przez sztuczkę, którą znalazłem.

function requireMany() { 
    return Array.prototype.slice.call(arguments).map(function (value) { 
     try { 
      return require(value) 
     } 
     catch (event) { 
      return console.log(event) 
     } 
    }) 
} 

I go używać jako takiego

requireMany("fs", "socket.io", "path") 

Który powróci

[ fs {}, socketio {}, path {} ] 

Jeżeli moduł nie zostanie znaleziony, błąd zostanie wysłana do konsoli. Nie złamie programu. Błąd zostanie wyświetlony w tablicy jako niezdefiniowany. Tablica nie będzie krótsza, ponieważ nie można załadować jednego z modułów.

Następnie można powiązać tych każdy z tych elementów tablicy do nazwy zmiennej, tak jak poniżej:

var [fs, socketio, path] = requireMany("fs", "socket.io", "path") 

To zasadniczo działa jak przedmiot, ale przypisuje klucze i wartości w globalnej przestrzeni nazw. Tak więc, w przypadku, można zrobić:

var [foo, bar] = requireMany("./foo.js", "./bar.js") 
foo() //return "hello from one" 
bar() //return "hello from two" 

A jeśli chcesz, aby przerwać program w przypadku błędu, po prostu skorzystać z tej zmodyfikowanej wersji, która jest mniejsza

function requireMany() { 
    return Array.prototype.slice.call(arguments).map(require) 
} 
Powiązane problemy