Modules in JavaScript
Working with multiple JS files in Vanilla JS application:
1. UMD - Import all files to index.html file with script tag,
- The order of files matter.
- The later imported .js file gets access to all the variables declared (let, const, var) and functions in the previously added files
Modules in JavaScript
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
hellow orld
<script src="index.js"></script>
<script src="mod1.js"></script>
<script src="mod2.js"></script>
</body>
</html>
// index.js
var ind = "100";
console.log({ ind });
console.log({ mod1 });
console.log({ cal: func1() });
console.log({ ind1 });
console.log({ ind2 });
// mod1.js
var ind1 = "200";
console.log("mod1", { ind1 });
const mod1 = 1000;
function func1() {
console.log("logged func");
}
// mod2.js
var ind2 = "300";
console.log("mod2", { ind2 });
Working with multiple JS files in Vanilla JS application:
- Adding a type="module" to the previously added .js files, now we cannot access any variable or function from mod1.js in any other file.
- But we cannot import/export variables across files yet.
- We need to add type="module" in both the files to export / import variables across
- Module scripts are always deferred
Modules in JavaScript
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
hellow orld
<script type="module" src="mod1.js"></script>
<script type="module" src="index.js"></script>
</body>
</html>
// index.js
import func1 from "./mod1.js";
var ind = "100";
console.log({ ind });
console.log({ modname: func1() });
// mod1.js
function func1() {
console.log("logged func");
return "10000";
}
export default func1;
Working with multiple JS files in Vanilla JS application:
- default exports / imports
- name in the import need NOT match the name in the export, can import the default export with any name,
- one file can have only 1 default export
- default exports do not need curly brackets ({}) at import
Modules in JavaScript
// index.js
import func1 from "./mod1.js";
console.log(func1());
// mod1.js
function func1() {
console.log("logged func");
return "10000";
}
export default func1;
// mod1.js
// just add "default"
export default class User {
constructor(name) {
this.name = name;
}
}
// index.js
import User from './user.js';
new User('John');
Working with multiple JS files in Vanilla JS application:
- default exports / imports - without name
- Not giving a name is fine, because there is only one export default per file, so import without curly braces knows what to import.
Modules in JavaScript
// index.js
import whateverName from "./mod1.js";
console.log(whateverName());
// no function name
export default function(user) {
alert(`Hello, ${user}!`);
}
Modules in JavaScript
// export an array
export let months = ['Jan', 'Feb', 'Mar']
// export a constant
export const MODULES_YEAR = 2015;
// export a class
export class User {
constructor(name) {
this.name = name;
}
}
Working with multiple JS files in Vanilla JS application:
- non-default exports / imports
- can export any declaration
- can add multiple exports statements
- Or we can line all the non-default exports together
// say.js
function sayHi(user) {
alert(`Hello, ${user}!`);
}
function sayBye(user) {
alert(`Bye, ${user}!`);
}
export {sayHi, sayBye};
Modules in JavaScript
import {sayHi, sayBye} from './say.js';
sayHi('John'); // Hello, John!
sayBye('John'); // Bye, John!
import * as say from './say.js';
say.sayHi('John');
say.sayBye('John');
Working with multiple JS files in Vanilla JS application:
- non-default exports are imported using curly brackets
- imports need to have same names as of exports,
- can import all at once and add alias to it as well
- unnamed non-default exports are not allowed
// Error! (non-default export needs a name)
export class {
constructor() {}
}
Modules in JavaScript
// say.js
function sayHi(user) {
alert(`Hello, ${user}!`);
}
function sayBye(user) {
alert(`Bye, ${user}!`);
}
export {sayHi as hi, sayBye as bye};
import {hi as sayingHi, bye as sayingBye} from './say.js';
sayingHi('John'); // Hello, John!
sayingBye('John'); // Bye, John!
Working with multiple JS files in Vanilla JS application:
- export aliasing / import aliasing
Modules in JavaScript
function sayHi(user) {
alert(`Hello, ${user}!`);
}
// same as if we added
// "export default" before
// the function
export {sayHi as default};
import saying from './user.js'; // works
import justKidding from './user.js'; // works too
Working with multiple JS files in Vanilla JS application:
- export aliasing as default
- import can be done just how a normal default export works
Modules in JavaScript
export default class User {
constructor(name) {
this.name = name;
}
}
export function sayHi(user) {
alert(`Hello, ${user}!`);
}
import {default as User, sayHi} from './user.js';
new User('John');
Working with multiple JS files in Vanilla JS application:
- a file can have both default exports and named (non-default) exports
- or using the default object
import * as user from './user.js';
// the default export
let User = user.default;
new User('John');
Modules in JavaScript
// import login/logout and immediately export them
import {login, logout} from './helpers.js';
export {login, logout};
// import default as User and export it
import User from './user.js';
export {User};
export {login, logout} from './helpers.js';
// re-export the default export as User
export {default as User} from './user.js';
// to re-export named exports
export * from './user.js';
export {default} from './user.js'
Working with multiple JS files in Vanilla JS application:
- exporting other functions from other files
Modules in JavaScript
export function hi() {
alert(`Hello`);
}
export function bye() {
alert(`Bye`);
}
Dynamic Imports:
- imports can be placed anywhere in the file but for convenience they are placed at the top
- imports cannot be placed in conditionals or loops,
- but sometimes you may need to import something dynamically based on some code etc.
- we can do it with .then/.catch instead of an await
let {hi, bye} = await import('./say.js');
hi();
bye();
import('./say.js')
.then(func => console.log(func()))
.catch(err => console.log(err))
Modules in JavaScript
Dynamic Imports:
- for cases of default exports
- Dynamic imports work in regular scripts, they don’t require script type="module"
let obj = await import('./say.js');
let say = obj.default;
export default function() {
alert("Module loaded (export default)!");
}
Modules in JavaScript
Dynamic Imports:
-
Although import() looks like a function call, it’s a special syntax that just happens to use parentheses (similar to super()).
-
So we can’t copy import to a variable or use call/apply with it. It’s not a function.
Modules in JavaScript
By Yash Priyam
Modules in JavaScript
- 91