ES Modules
IIFE
A way to make file’s data non-global is to use IIFE:
(function () { statements})();
This way, if we add some JS file to HTML, we’ll not be able to access that JS’s data from the HTML file (encapsulation).
Modules are better for that.
ES6 Modules
Modules characterics:
- they are singletons - every file that imports the module gets the same thing. If something gets modified in exported module by some client, all other clients will see that
- one module is one file
Exporting
There are a few ways to export a module:
Named Export
Contents of myModule.js
export function functionOne() {...}function functionTwo() {...}export someValue = 4
OR
function functionOne() {...}function functionTwo() {...}someValue = 4
export {functionOne, someValue}
Only functionOne
and someValue
get exported. The functionTwo
is not
visible to the clients of this module.
To import it:
import { functionOne } from './myModule.js'
We can skip someValue
if we don’t need it.
We can change the name of the exported entity:
export {functionOne as myFunction, someValue}
Then we’d import it like this:
import { myFunction } from './myModule.js'
Export Default
Contents of myModule.js
export default function functionOne() {...}function functionTwo() {...}export someValue = 4
OR
function functionOne() {...}function functionTwo() {...}someValue = 4
export {functionOne as default, someValue}
Only one thing can be exported as default. The client:
import someFunc from 'myModule.js'someFunc()
The client does not have to know the name of the thing he imports.
Aggregate Exports
One module can export another module, so that the consumer uses just one “import”.
export {functionOne as default, someValue}export {functionThree} from './anotherModule.js'
functionThree
is not accessible to that aggreagate module, it just exports it
for the consumers of it (however, it could improt it and make use of it also).
Importing
HTML
<script src="app.js" type="module"></script>
Default Import
If module exports something as default, we can import it with any name:
import something from 'myModule.js'
Named Import
import { myFunction } from './myModule.js'
We can change name in the client:
import { myFunction as func } from './myModule.js'
We can import all that was exported:
import * as myModule from 'myModule.js'
myModule.functionOne();
Mixed Import
import something, {someValue} from 'myModule.js'
OR
import something, * as stuff from 'myModule.js'