Konceptet med moduler kommer från det modulära programmeringsparadigmet. Detta paradigm föreslår att mjukvara ska vara sammansatt av separata, utbytbara komponenter som kallas "moduler" genom att dela upp programfunktioner till fristående filer som kan fungera separat eller kopplade i en Ansökan.

En modul är en fristående fil som kapslar in kod för att implementera viss funktionalitet och främja återanvändbarhet och organisation.

Här kommer du att täcka modulsystemen som används i JavaScript-applikationer, inklusive modulmönstret, CommonJS-modulsystemet som används i de flesta Node.js-applikationer och ES6 Module-systemet.

Modulmönstret

Innan introduktionen av inbyggda JavaScript-moduler användes moduldesignmönstret som ett modulsystem för att omfånga variabler och funktioner till en enda fil.

Detta implementerades med omedelbart anropade funktionsuttryck, populärt kända som IIFEs. En IIFE är en funktion som inte kan återanvändas som körs så snart den skapas.

Här är den grundläggande strukturen för en IIFE:

instagram viewer
(fungera () {
//kod här
})();

(() => {
//kod här
})();

(asynkron () => {
//kod här
})();

Kodblocket ovan beskriver IIFE: er som används i tre olika sammanhang.

IIFE: er användes eftersom variabler som deklareras inuti en funktion är scoped till funktionen, vilket gör dem endast tillgänglig inuti funktionen, och eftersom funktioner låter dig returnera data (gör dem offentligt tillgänglig).

Till exempel:

konst foo = (fungera () {
konst sayName = (namn) => {
trösta.logga("Hej, jag heter ${name}`);
};
//Exponera variablerna
lämna tillbaka {
callSayName: (namn) => sayName (namn),
};
})();
//Åtkomst till exponerade metoder
foo.callSayName("Bar");

Kodblocket ovan är ett exempel på hur moduler skapades innan introduktionen av inbyggda JavaScript-moduler.

Kodblocket ovan innehåller en IIFE. IIFE innehåller en funktion som den gör tillgänglig genom att returnera den. Alla variabler som deklareras i IIFE är skyddade från den globala räckvidden. Alltså metoden (säg Namn) är endast tillgänglig via den offentliga funktionen, callSayName.

Lägg märke till att IIFE sparas i en variabel, foo. Detta beror på att, utan att en variabel pekar på dess plats i minnet, kommer variablerna att vara otillgängliga efter att skriptet körts. Detta mönster är möjligt pga JavaScript-stängningar.

CommonJS-modulsystemet

CommonJS-modulsystemet är ett modulformat som definieras av CommonJS-gruppen för att lösa problem med JavaScript-omfattning genom att exekvera varje modul i dess namnområde.

CommonJS-modulsystemet fungerar genom att tvinga moduler att explicit exportera variabler som de vill exponera till andra moduler.

Detta modulsystem skapades för JavaScript på serversidan (Node.js) och, som sådan, stöds inte som standard i webbläsare.

För att implementera CommonJS-moduler i ditt projekt måste du först initiera NPM i din applikation genom att köra:

npm init -y

Variabler som exporteras efter CommonJS-modulsystemet kan importeras så här:

//randomModule.js
//installerat paket
konst installeradImport = behöva("Paketnamn");
//lokal modul
konst localImport = behöva("/path-to-module");

Moduler importeras i CommonJS med hjälp av behöva uttalande, som läser en JavaScript-fil, kör läsfilen och returnerar export objekt. De export objektet innehåller alla tillgängliga exporter i modulen.

Du kan exportera en variabel efter CommonJS-modulsystemet med antingen namngivna exporter eller standardexporter.

Namngivna exporter

Namngivna exporter är exporter som identifieras av de namn de tilldelats. Namngivna exporter tillåter flera exporter per modul, till skillnad från standardexporter.

Till exempel:

//main.js
exports.myExport = fungera () {
trösta.log("Detta är ett exempel av en namngiven exportera");
};
exports.anotherExport = fungera () {
trösta.log("Detta är ett annat exempel av en namngiven exportera");
};

I kodblocket ovan exporterar du två namngivna funktioner (myExport och annan Export) genom att fästa dem på export objekt.

På samma sätt kan du exportera funktionerna så här:

konst myExport = fungera () {
trösta.log("Detta är ett exempel av en namngiven exportera");
};
konst anotherExport = fungera () {
trösta.log("Detta är ett annat exempel av en namngiven exportera");
};
modul.export = {
myExport,
annan export,
};

I kodblocket ovan ställer du in export invända mot de namngivna funktionerna. Du kan bara tilldela export objekt till ett nytt objekt genom modul objekt.

Din kod skulle ge ett felmeddelande om du försökte göra det på detta sätt:

//fel väg
export = {
myExport,
annan export,
};

Det finns två sätt att importera namngivna exporter:

1. Importera alla exporter som ett enda objekt och få tillgång till dem separat med punktnotationen.

Till exempel:

//otherModule.js
konst foo = behöva("./main");
foo.myExport();
foo.anotherExport();

2. Destrukturera exporten från export objekt.

Till exempel:

//otherModule.js
konst { myExport, anotherExport } = behöva("./main");
myExport();
anotherExport();

En sak är gemensam i alla metoder för import, de måste importeras med samma namn som de exporterades med.

Standardexporter

En standardexport är en export som identifieras med valfritt namn. Du kan bara ha en standardexport per modul.

Till exempel:

//main.js
klassFoo{
bar() {
trösta.log("Detta är ett exempel av a standardexportera");
}
}
modul.export = Foo;

I kodblocket ovan exporterar du en klass (Foo) genom att tilldela om export invända mot det.

Att importera standardexporter liknar att importera namngivna exporter, förutom att du kan använda valfritt namn för att importera dem.

Till exempel:

//otherModule.js
konst Bar = behöva("./main");
konst objekt = ny Bar();
objekt.bar();

I kodblocket ovan namngavs standardexporten Bar, även om du kan använda valfritt namn.

ES6-modulsystemet

ECMAScript Harmony-modulsystem, populärt känt som ES6-moduler, är det officiella JavaScript-modulsystemet.

ES6-moduler stöds av webbläsare och servrar, även om du kräver lite konfiguration innan du använder dem.

I webbläsare måste du ange typ som modul i skriptimporttaggen.

Såhär:

//index.html
<script src="./app.js" typ="modul"></script>

I Node.js måste du ställa in typ till modul i din package.json fil.

Såhär:

//package.json
"typ":"modul"

Du kan också exportera variabler med ES6-modulsystemet med antingen namngivna exporter eller standardexporter.

Namngivna exporter

I likhet med namngivna importer i CommonJS-moduler identifieras de av namnen de tilldelades och tillåter flera exporter per modul.

Till exempel:

//main.js
exporterakonst myExport = fungera () {
trösta.log("Detta är ett exempel av en namngiven exportera");
};
exporterakonst anotherExport = fungera () {
trösta.log("Detta är ett annat exempel av en namngiven exportera");
};

I ES6-modulsystemet exporteras namngivna exporter genom att prefixet för variabeln exportera nyckelord.

Namngivna exporter kan importeras till en annan modul i ES6 på samma sätt som CommonJS:

  • Destrukturering av den nödvändiga exporten från export objekt.
  • Importera alla exporter som ett enda objekt och åtkomst till dem separat med hjälp av punktnotationen.

Här är ett exempel på destrukturering:

//otherModule.js
importera { myExport, anotherExport } från "./main.js";
myExport()
anotherExport()

Här är ett exempel på hur du importerar hela objektet:

importera * som foo från './main.js'
foo.myExport()
foo.anotherExport()

I kodblocket ovan visas asterisken (*) betyder "alla". De som nyckelordet tilldelar export invända mot strängen som följer den, i det här fallet, foo.

Standardexporter

I likhet med standardexporter i CommonJS identifieras de med valfritt namn och du kan bara ha en standardexport per modul.

Till exempel:

//main.js
klassFoo{
bar() {
trösta.log("Detta är ett exempel av a standardexportera");
}
}
exporterastandard Foo;

Standardexporter skapas genom att lägga till standard nyckelord efter exportera nyckelord, följt av namnet på exporten.

Att importera standardexporter liknar att importera namngivna exporter, förutom att du kan använda valfritt namn för att importera dem.

Till exempel:

//otherModule.js
importera Bar från "./main.js";

Blandad export

ES6-modulstandarden låter dig ha både standardexporter och namngivna exporter i en modul, till skillnad från CommonJS.

Till exempel:

//main.js
exporterakonst myExport = fungera () {
trösta.log("Detta är ett annat exempel av en namngiven exportera");
};
klassFoo{
bar() {
trösta.log("Detta är ett exempel av a standardexportera");
}
}
exporterastandard Foo;

Vikten av moduler

Att dela upp din kod i moduler gör dem inte bara lättare att läsa utan det gör den mer återanvändbar och även underhållbar. Moduler i JavaScript gör också din kod mindre felbenägen, eftersom alla moduler körs i strikt läge som standard.