As our JavaScript code grows in site, there comes a times where including one file in not enough- here we're having a look at how to structure code across multiple files using modules.
Enable modules
Given an index.html
file that includes a app.js
file using a script
tag, to enable module, we'll have to include type="module"
:
<html>
<head>...</head>
<body>
...
<script src="app.js" type="module"></script>
</body>
</html>
index.html
Default Import/Export
Now, can include functions defines in other files:
import f1 from './dependency.js';
...
f1();
app.js
... where f1 is exported from within the dependency:
function f1() {
...
}
export { f1 as default };
dependency.js
Named Import/Export
An alternative that is usually used when multiple 'transfers' are required is using named exports/imports:
function f1() {
...
}
function f2() {
...
}
export { f1, f2};
dependency.js
On import, the names must match the exact names from export (order not relevant):
import {f1, f2} from './dependency.js';
...
f1();
app.js
Renamed Export
Function can be renamed as part of the export:
function f1() {
...
}
function f2() {
...
}
export { f1, f2 as f3};
dependency.js
Now, it's imported as f3
:
import {f1, f3} from './dependency.js';
...
f3();
app.js
Renamed Import
Function can also be renamed as part of the import:
function f1() {
...
}
function f2() {
...
}
export { f1, f2};
dependency.js
Now, it's imported as f3
:
import {f1, f2 as f3} from './dependency.js';
...
f3();
app.js
Inline exports
The exports can also happen inline for each function that needs it:
export function f1() {
...
}
export function f2() {
...
}
dependency.js
Combined imports: Default & Named
Both of the previous methods can be combined for some interesting results:
function f1() {
...
}
function f2() {
...
}
export { f1 as default, f2};
dependency.js
Now, the import might look a bit strange:
import f1, {f2} from './dependency.js';
app.js
Passthrough Exports
Say we have 2 dependencies and we don't want to have to import both.
Given a second dependency:
function f2() {
...
}
export { f2 };
dependency2.js
We can simply "pass it through" in the first dependency:
function f1() {
...
}
export { f1 };
export { f2 } from './dependency2.js';
dependency1.js
Now app.js
will only have to import from one dependency:
import {f1, f2} from './dependency1.js';
app.js
Import all
A great technique that sames keystrokes on import is the ability to import all functions together.
Given:
function f1() {
...
}
function f2() {
...
}
export { f1, f2};
dependency.js
All exports can be imported together, but the usage is slightly different:
import * as dependant from './dependency.js';
dependant.f1();
app.js
Finally
Classes can also be exported and imported.
Unfortunately, modules are not available in IE (see MDN docs) but are in Edge.
To achieve backward compatibility and avoid multiple HTTP requests in a production environment, we should probably use a module bundler such as Webpack or Babel.
Top comments (0)