Node.js
Modules exporteren en consumeren
Zoeken…
Opmerkingen
Hoewel alles in Node.js over het algemeen asynchroon wordt gedaan, is require()
niet een van die dingen. Aangezien modules in de praktijk slechts eenmaal hoeven te worden geladen, is dit een blokkeerbewerking en moeten ze correct worden gebruikt.
Modules worden in de cache opgeslagen nadat ze voor het eerst zijn geladen. Als u een module in ontwikkeling bewerkt, moet u de invoer in de modulecache verwijderen om nieuwe wijzigingen te kunnen gebruiken. Dat gezegd hebbende, zelfs als een module uit de modulecache wordt gewist, wordt de module zelf niet verzameld, dus wees voorzichtig met het gebruik ervan in productieomgevingen.
Een module laden en gebruiken
Een module kan worden "geïmporteerd", of anderszins "vereist" door de require()
-functie. Om bijvoorbeeld de http
module te laden die wordt geleverd met Node.js, kan het volgende worden gebruikt:
const http = require('http');
Naast modules die met de runtime worden meegeleverd, kunt u ook modules nodig hebben die u vanaf npm hebt geïnstalleerd, zoals Express. Als je al express op je systeem had geïnstalleerd via npm install express
, zou je eenvoudig kunnen schrijven:
const express = require('express');
U kunt ook modules opnemen die u zelf hebt geschreven als onderdeel van uw toepassing. In dit geval, om een bestand met de naam lib.js
in dezelfde map als het huidige bestand:
const mylib = require('./lib');
Merk op dat u de extensie kunt weglaten, en .js
wordt verondersteld. Nadat u een module heeft geladen, wordt de variabele gevuld met een object dat de methoden en eigenschappen bevat die zijn gepubliceerd vanuit het vereiste bestand. Een volledig voorbeeld:
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);
Een hello-world.js-module maken
Node biedt de module.exports
interface om functies en variabelen aan andere bestanden bloot te stellen. De meest eenvoudige manier om dit te doen is om slechts één object (functie of variabele) te exporteren, zoals getoond in het eerste voorbeeld.
hello-world.js
module.exports = function(subject) {
console.log('Hello ' + subject);
};
Als we niet willen dat de gehele export één object is, kunnen we functies en variabelen exporteren als eigenschappen van het exports
. De drie volgende voorbeelden tonen dit allemaal op enigszins verschillende manieren aan:
- hello-venus.js: de functiedefinitie wordt afzonderlijk gedaan en vervolgens toegevoegd als een eigenschap van
module.exports
- hello-jupiter.js: de functiedefinities worden direct gezet als de waarde van eigenschappen van
module.exports
- hello-mars.js: de functiedefinitie wordt rechtstreeks gedeclareerd als een eigenschap van
exports
, een korte versie vanmodule.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);
};
Laadmodule met mapnaam
We hebben een map met de naam hello
die de volgende bestanden bevat:
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'
De modulecache ongeldig maken
In de ontwikkeling kan het zijn dat het meerdere keren gebruiken require()
op dezelfde module altijd dezelfde module retourneert, zelfs als u wijzigingen in dat bestand hebt aangebracht. De reden hiervoor is dat modules in de cache worden geplaatst wanneer ze voor het eerst worden geladen en dat alle volgende module-ladingen uit de cache worden geladen.
Om dit probleem te omzeilen, moet delete
het item in de cache verwijderen. Als u bijvoorbeeld een module heeft geladen:
var a = require('./a');
U kunt dan de cache-invoer verwijderen:
var rpath = require.resolve('./a.js');
delete require.cache[rpath];
En vereist dan de module opnieuw:
var a = require('./a');
Houd er rekening mee dat dit niet wordt aanbevolen tijdens de productie, omdat bij het delete
alleen de verwijzing naar de geladen module wordt verwijderd, niet de geladen gegevens zelf. De module wordt niet als afval verzameld, dus onjuist gebruik van deze functie kan leiden tot lekkend geheugen.
Bouw je eigen modules
U kunt ook naar een object verwijzen om het publiekelijk te exporteren en continu methoden aan dat object toevoegen:
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
}
Om een van deze te gebruiken, heeft u de module nodig zoals u normaal zou doen:
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()
})
}
Elke module slechts één keer geïnjecteerd
NodeJS voert de module alleen uit wanneer u deze de eerste keer nodig hebt. Eventuele verdere functies zullen hetzelfde object opnieuw gebruiken, waardoor de code in een andere module niet opnieuw wordt uitgevoerd. Ook knoopt de Node de modules de eerste keer dat ze worden geladen met behulp van vereist. Dit vermindert het aantal gelezen bestanden en helpt de toepassing te versnellen.
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
Module laden vanuit node_modules
Modules kunnen require
zonder relatieve paden te gebruiken door ze in een speciale map met de naam node_modules
.
Bijvoorbeeld, om require
een module genaamd foo
uit een bestand index.js
, kunt u gebruik maken van de volgende directory structuur:
index.js
\- node_modules
\- foo
|- foo.js
\- package.json
Modules moeten in een map worden geplaatst, samen met een package.json
bestand. De main
gebied van de package.json
bestand moet verwijzen naar de ingang voor uw module - dit is het bestand dat wordt geïmporteerd wanneer gebruikers require('your-module')
. main
standaardwaarden voor index.js
indien niet opgegeven. U kunt ook naar bestanden verwijzen die relatief zijn aan uw module door het relatieve pad toe te voegen aan de require
aanroep: require('your-module/path/to/file')
.
Modules kunnen ook require
uit mappen met node_modules
in de hiërarchie van het bestandssysteem. Als we de volgende mapstructuur hebben:
my-project
\- node_modules
|- foo // the foo module
\- ...
\- baz // the baz module
\- node_modules
\- bar // the bar module
zullen we in staat zijn om require
de module foo
uit een bestand in bar
met behulp van require('foo')
.
Merk op dat het knooppunt alleen overeenkomt met de module die zich het dichtst bij het bestand in de bestandssysteemhiërarchie bevindt, beginnend bij (de huidige map van het bestand / knooppuntmodules). Node matcht mappen op deze manier tot de root van het bestandssysteem.
U kunt nieuwe modules installeren vanuit het npm-register of andere npm-registers, of uw eigen modules maken.
Map als een module
Modules kunnen worden verdeeld over vele .js-bestanden in dezelfde map. Een voorbeeld in een map 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');
Een module zoals deze wordt gebruikt door ernaar te verwijzen met de mapnaam:
var split_module = require('./my_module');
Houd er rekening mee dat als u dit nodig hebt door ./
of een indicatie van een pad naar een map uit het vereiste functieargument weg te laten, Node probeert een module te laden vanuit de map node_modules .
Als alternatief kunt u in dezelfde map een package.json
bestand met deze inhoud maken:
{
"name": "my_module",
"main": "./your_main_entry_point.js"
}
Op deze manier hoeft u het hoofdmodulebestand niet "index" te noemen.