Node.js
Eksportowanie i używanie modułów
Szukaj…
Uwagi
Podczas gdy wszystko w Node.js jest generalnie wykonywane asynchronicznie, metoda need require()
nie jest jedną z tych rzeczy. Ponieważ moduły w praktyce muszą być ładowane tylko raz, jest to operacja blokująca i powinna być używana prawidłowo.
Moduły są buforowane po pierwszym załadowaniu. Jeśli edytujesz moduł w fazie rozwoju, będziesz musiał usunąć jego wpis z pamięci podręcznej modułu, aby użyć nowych zmian. Biorąc to pod uwagę, nawet jeśli moduł zostanie wyczyszczony z pamięci podręcznej modułu, sam moduł nie jest usuwany, dlatego należy zachować ostrożność podczas jego używania w środowiskach produkcyjnych.
Ładowanie i używanie modułu
Moduł może zostać „zaimportowany” lub w inny sposób „wymagany” przez funkcję require()
. Na przykład, aby załadować moduł http
dostarczany z Node.js, można użyć następujących opcji:
const http = require('http');
Oprócz modułów dostarczanych wraz ze środowiskiem wykonawczym możesz także wymagać modułów zainstalowanych z npm, takich jak express. Jeśli już zainstalowałeś express w swoim systemie za pomocą npm install express
, możesz po prostu napisać:
const express = require('express');
Możesz także dołączyć moduły, które sam napisałeś jako część aplikacji. W takim przypadku, aby dołączyć plik o nazwie lib.js
do tego samego katalogu, co bieżący plik:
const mylib = require('./lib');
Zauważ, że możesz pominąć rozszerzenie, i .js
zostanie założony. Po załadowaniu modułu zmienna jest zapełniana obiektem, który zawiera metody i właściwości opublikowane z wymaganego pliku. Pełny przykład:
const http = require('http');
// The `http` module has the property `STATUS_CODES`
console.log(http.STATUS_CODES[404]); // outputs 'Not Found'
// Also contains `createServer()`
http.createServer(function(req, res) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.write('<html><body>Module Test</body></html>');
res.end();
}).listen(80);
Tworzenie modułu hello-world.js
Węzeł udostępnia interfejs module.exports
celu udostępnienia funkcji i zmiennych innym plikom. Najprostszym sposobem jest wyeksportowanie tylko jednego obiektu (funkcji lub zmiennej), jak pokazano w pierwszym przykładzie.
hello-world.js
module.exports = function(subject) {
console.log('Hello ' + subject);
};
Jeśli nie chcemy, aby cały eksport był pojedynczym obiektem, możemy wyeksportować funkcje i zmienne jako właściwości obiektu exports
. Trzy poniższe przykłady pokazują to w nieco inny sposób:
- hello-venus.js: definicja funkcji jest wykonywana osobno, a następnie dodawana jako właściwość
module.exports
- hello-jupiter.js: definicje funkcji są umieszczane bezpośrednio jako wartość właściwości
module.exports
- hello-mars.js: definicja funkcji jest bezpośrednio zadeklarowana jako właściwość
exports
która jest krótką wersjąmodule.exports
hello-venus.js
function hello(subject) {
console.log('Venus says Hello ' + subject);
}
module.exports = {
hello: hello
};
hello-jupiter.js
module.exports = {
hello: function(subject) {
console.log('Jupiter says hello ' + subject);
},
bye: function(subject) {
console.log('Jupiter says goodbye ' + subject);
}
};
hello-mars.js
exports.hello = function(subject) {
console.log('Mars says Hello ' + subject);
};
Ładowanie modułu z nazwą katalogu
Mamy katalog o nazwie hello
który zawiera następujące pliki:
index.js
// hello/index.js
module.exports = function(){
console.log('Hej');
};
main.js
// hello/main.js
// We can include the other files we've defined by using the `require()` method
var hw = require('./hello-world.js'),
hm = require('./hello-mars.js'),
hv = require('./hello-venus.js'),
hj = require('./hello-jupiter.js'),
hu = require('./index.js');
// Because we assigned our function to the entire `module.exports` object, we
// can use it directly
hw('World!'); // outputs "Hello World!"
// In this case, we assigned our function to the `hello` property of exports, so we must
// use that here too
hm.hello('Solar System!'); // outputs "Mars says Hello Solar System!"
// The result of assigning module.exports at once is the same as in hello-world.js
hv.hello('Milky Way!'); // outputs "Venus says Hello Milky Way!"
hj.hello('Universe!'); // outputs "Jupiter says hello Universe!"
hj.bye('Universe!'); // outputs "Jupiter says goodbye Universe!"
hu(); //output 'hej'
Unieważnienie pamięci podręcznej modułu
W fazie rozwoju może się okazać, że wielokrotne użycie require()
w tym samym module zawsze zwraca ten sam moduł, nawet jeśli dokonałeś zmian w tym pliku. Wynika to z tego, że moduły są buforowane przy pierwszym załadowaniu, a wszelkie kolejne ładunki modułów będą ładowane z pamięci podręcznej.
Aby obejść ten problem, musisz delete
wpis z pamięci podręcznej. Na przykład, jeśli załadowałeś moduł:
var a = require('./a');
Następnie możesz usunąć wpis w pamięci podręcznej:
var rpath = require.resolve('./a.js');
delete require.cache[rpath];
A następnie ponownie wymagaj modułu:
var a = require('./a');
Należy pamiętać, że nie jest to zalecane w produkcji, ponieważ delete
spowoduje jedynie usunięcie odniesienia do załadowanego modułu, a nie samych załadowanych danych. Moduł nie jest odśmiecany, więc nieprawidłowe użycie tej funkcji może doprowadzić do wycieku pamięci.
Budowanie własnych modułów
Możesz także odwoływać się do obiektu, aby publicznie eksportować i stale dodawać metody do tego obiektu:
const auth = module.exports = {}
const config = require('../config')
const request = require('request')
auth.email = function (data, callback) {
// Authenticate with an email address
}
auth.facebook = function (data, callback) {
// Authenticate with a Facebook account
}
auth.twitter = function (data, callback) {
// Authenticate with a Twitter account
}
auth.slack = function (data, callback) {
// Authenticate with a Slack account
}
auth.stack_overflow = function (data, callback) {
// Authenticate with a Stack Overflow account
}
Aby użyć dowolnego z nich, wystarczy moduł, tak jak zwykle:
const auth = require('./auth')
module.exports = function (req, res, next) {
auth.facebook(req.body, function (err, user) {
if (err) return next(err)
req.user = user
next()
})
}
Każdy moduł jest wstrzykiwany tylko raz
NodeJS wykonuje moduł tylko wtedy, gdy go potrzebujesz. Wszelkie dalsze funkcje będą wymagały ponownego użycia tego samego obiektu, co nie spowoduje wykonania kodu w module innym razem. Również Węzeł buforuje moduły przy pierwszym załadowaniu, używając wymagania. Zmniejsza to liczbę odczytów plików i pomaga przyspieszyć aplikację.
myModule.js
console.log(123) ;
exports.var1 = 4 ;
index.js
var a=require('./myModule') ; // Output 123
var b=require('./myModule') ; // No output
console.log(a.var1) ; // Output 4
console.log(b.var1) ; // Output 4
a.var2 = 5 ;
console.log(b.var2) ; // Output 5
Ładowanie modułu z modułów node_modules
Moduły mogą require
d bez użycia ścieżek względnych, umieszczając je w specjalnym katalogu o nazwie node_modules
.
Na przykład, aby require
modułu o nazwie foo
z pliku index.js
, możesz użyć następującej struktury katalogów:
index.js
\- node_modules
\- foo
|- foo.js
\- package.json
Moduły należy umieścić w katalogu wraz z plikiem package.json
. main
pole pliku package.json
powinno wskazywać punkt wejścia dla modułu - jest to plik importowany, gdy require('your-module')
tego użytkownicy require('your-module')
. main
wartości domyślne to index.js
jeśli nie podano. Alternatywnie, możesz odwoływać się do plików względem twojego modułu, po prostu dodając ścieżkę względną do require
wywołania: require('your-module/path/to/file')
.
Moduły mogą również require
d od katalogów node_modules
górę hierarchii systemu plików. Jeśli mamy następującą strukturę katalogów:
my-project
\- node_modules
|- foo // the foo module
\- ...
\- baz // the baz module
\- node_modules
\- bar // the bar module
będziemy mogli require
modułu foo
z dowolnego pliku w bar
za pomocą require('foo')
.
Zauważ, że węzeł będzie pasował tylko do modułu znajdującego się najbliżej pliku w hierarchii systemu plików, zaczynając od (bieżący katalog pliku / moduły_węzła). Węzeł dopasowuje katalogi w ten sposób do katalogu głównego systemu plików.
Możesz zainstalować nowe moduły z rejestru npm lub innych rejestrów npm lub utworzyć własne.
Folder jako moduł
Moduły można podzielić na wiele plików .js w tym samym folderze. Przykład w folderze my_module :
function_one.js
module.exports = function() {
return 1;
}
function_two.js
module.exports = function() {
return 2;
}
index.js
exports.f_one = require('./function_one.js');
exports.f_two = require('./function_two.js');
Moduł taki jak ten jest używany przez odniesienie do niego przez nazwę folderu:
var split_module = require('./my_module');
Należy pamiętać, że jeśli jest to wymagane przez pominięcie ./
lub jakiegokolwiek wskazania ścieżki do folderu z argumentu funkcji wymaganej, Node spróbuje załadować moduł z folderu node_modules .
Alternatywnie możesz utworzyć w tym samym folderze plik package.json
z następującą zawartością:
{
"name": "my_module",
"main": "./your_main_entry_point.js"
}
W ten sposób nie musisz nazywać głównego pliku modułu „indeksem”.