05 - ES Modules and Libraries
05 - ES Modules and Libraries
What is ES6 ?
ES6 Features
Introduction to ES Modules
Why is understanding the JS Module System important?
Different Types of JS Module Systems ?
Luxon - Overview
What is ES6?
JavaScript ES6 (also known as ECMAScript 2015 or ECMAScript 6) is the newer version of JavaScript that was introduced in 2015. ECMAScript is th
standard that JavaScript programming language uses. ECMAScript provides the specification on how JavaScript programming language should work.
ES6 Features
JavaScript let
JavaScript let is used to declare variables. Previously, variables were declared using the var keyword.
The variables declared using let are block-scoped. This means they are only accessible within a particular block. For example,
console.log(name); // Peter
}
console.log(name); // Sara
JavaScript const
The const statement is used to declare constants in JavaScript. For example,
// function expression
let x = function(x, y) {
return x * y;
}
can be written as
JavaScript Classes
JavaScript class is used to create an object. Class is similar to a constructor function. For example,
class Person {
constructor(
constructor(name
name)
) {
this.
this.name = name
name;
;
}
}
Keyword class is used to create a class. The properties are assigned in a constructor function.
Now you can create an object. For example,
class Person {
constructor(
constructor(name
name)
) {
this.
this.name = name
name;
;
}
}
Person(
const person1 = new Person('John'
'John')
);
console.
console.log
log(
(person1
person1..name
name)
); // John
sum(
function sum(x, y = 5) {
// take sum
// the value of y is 5 if not passed
console.
console.log
log(
(x + y)
y);
}
sum(
sum(5); // 10
sum(
sum(5, 15
15)
); // 20
In the above example, if you don't pass the parameter for y , it will take 5 by default.
console.
console.log
log(
('Hello ' + first_name + ' ' + last_name
last_name)
);
console.
console.log
log(
(`Hello ${
${first_name
first_name}
} ${
${last_name
last_name}
}`);
JavaScript Destructuring
The destructuring syntax makes it easier to assign values to a new variable. For example,
console.log(name); // Sara
console.log(age); // 25
console.log(gender); // female
Using ES6 Destructuring syntax, the above code can be written as:
const person = {
name: 'Sara',
age: 25,
gender: 'female'
}
console.log(name); // Sara
console.log(age); // 25
console.log(gender); // female
// export
export default function contact(name, age) {
console.log(`The name is ${name}. And age is ${age}.`);
}
Then when you want to use the contact() function in another file, you can simply import the function. For example, in home.js file:
contact('Sara', 25);
// The name is Sara. And age is 25
JavaScript Promises
Promises are used to handle asynchronous tasks. For example,
// returns a promise
let countValue = new Promise(function (resolve, reject) {
reject('Promise rejected');
});
show(
function show(a, b
b,
, ... args)
...args ) {
console.
console.log
log(
(a); // one
console.
console.log
log(
(b); // two
console.
console.log
log(
(args
args)
); // ["three", "four", "five", "six"]
}
show(
show('one'
'one',
, 'two'
'two',, 'three'
'three',
, 'four'
'four',
, 'five'
'five',
, 'six'
'six'))
You pass the remaining arguments using ... syntax. Hence, the name rest parameter.
You use the spread syntax ... to copy the items into a single array. For example,
Both the rest parameter and the spread operator use the same syntax. However, the spread operator is used with arrays (iterable values).
Introduction to ES Modules
ES Modules is the ECMAScript standard for working with modules. While Node.js has been using the CommonJS standard since years, the browse
never had a module system, as every major decision such as a module system must be first standardized by ECMAScript and then implemented
require(
const package = require ('module-name'
'module-name'))
Module is a file that contains code to perform a specific task. A module may contain variables, functions, classes etc. Let's see an example,
Suppose, a file named greet.js contains the following code:
// exporting a function
greetPerson(
export function greetPerson (name
name)
) {
${name
return `Hello ${name}
}`;
}
Now, to use the code of greet.js in another file, you can use the following code:
console.
console.log
log(
(displayName
displayName)); // Hello Jack
Here,
The greetPerson() function in the greet.js is exported using the export keyword
console.
console.log
log(
(displayName
displayName)); // Hello Jack
Then, we imported greetPerson() in another file using the import keyword. To import functions, objects, etc., you need to wrap them around { }.
'/.greet.js';
import { greet } from '/.greet.js';
Note: You can only access exported functions, objects, etc. from the module. You need to use the export keyword for the particular
function, objects, etc. to import them and use them in other files.
In main file,
name,
import { name, sum } from './module.js'
'./module.js';;
console.
console.log
log(
(name
name)
);
sum(
let add = sum(4, 9);
console.
console.log
log(
(add
add)
); // 13
Here,
name,
import { name, sum } from './module.js'
'./module.js';;
This imports both the name variable and the sum() function from the module.js file.
Here, while exporting the function from module.js file, new names (here, newName1 & newName2 ) are given to the function. Hence, when importing th
function, the new name is used to reference that function.
// inside module.js
export {
function1,
function1,
function2
};
newName1,
import { function1 as newName1, function2 as newName2 } from './module.js'
'./module.js';
;
Here, while importing the function, the new names (here, newName1 & newName2 ) are used for the function name. Now you use the new names
reference these functions.
Default Export
You can also perform default export of the module. For example,
In the file greet.js:
// default export
greet(
export default function greet (name
name)
) {
${name
return `Hello ${name}
}`;
}
export const age = 23;
random_name is imported from greet.js . Since, random_name is not in greet.js , the default export ( greet() in this case) is
exported as random_name .
You can directly use the default export without enclosing curly brackets {} .
Note: A file can contain multiple exports. However, you can only have one default export in a file.
// in greet.js
function greet() {
// strict by default
}
export greet();
Telling stories is as basic to human beings as eating. More so, in fact, for while food makes us live, stories are what make our lives worth
living - Richard Kearney.
There were many common functionalities required across projects. We always end up copy-pasting those functionalities to new projects over and ove
again.
The problem was that whenever one piece of the code changed, We needed to manually sync those changes across all my projects. To avoid all thes
tedious manual tasks, We planned to extract the common functionalities and compose an npm package out of them. This way, others on the team wou
be able to re-use them as dependencies and simply update them whenever a new release was rolled out.
If there was some change in the core library, then a change only had to be made in one place without refactoring all the applications’
code for the same thing.
All the applications remained in sync. Whenever a change was made, all the applications just needed to run the “npm update” command.
So, the next step was to publish the library
This was the toughest part, because there were a bunch of things bouncing around our heads, like:
Everyone of us has had these kind of questions bubbling in our heads while creating a library. Right?
1. CommonJS
Implemented by node
Used for the server side when you have modules installed
No runtime/async module loading
import via “require”
export via “module.exports”
When you import you get back an object
No tree shaking, because when you import you get an object
No static analyzing, as you get an object, so property lookup is at runtime
You always get a copy of an object, so no live changes in the module itself
Poor cyclic dependency management
Simple Syntax
Implemented by RequireJs
Used for the client side (browser) when you want dynamic loading of modules
Import via “require”
Complex Syntax
Combination of Commonjs + AMD (that is, Syntax of CommonJs + async loading of AMD)
Can be used for both AMD/CommonJs environments
UMD essentially creates a way to use either of the two, while also supporting the global variable definition. As a result, UMD modules are
capable of working on both client and server.
Conclusion
ES Modules are one of the biggest features introduced in modern browsers. They are part of ES6 but the road to implement them has been long.
We can now use them! But we must also remember that having more than a few modules is going to have a performance hit on our pages, as it’s on
more step that the browser must perform at runtime.
Prior to the introduction of the ES6 standard, there wasn’t any native implementation for organizing source code in server-side JavaScript. Th
community relied heavily on CommonJS module format.
Nowadays, with the introduction and API stabilization of ES modules, developers can enjoy the many benefits associated with the release specificatio
This article has highlighted the transition between both module systems and their interoperability.
myVariable = 9;
Here, myVariable is created without declaring. This works as a global variable in JavaScript. However, if you use this in strict mode, the program w
throw an error. For example,
'use strict';
// Error
myVariable = 9;
The above code throws an error because myVariable is not declared. In strict mode, you cannot use the variable without declaring them.
To indicate this program is in the strict mode, we have used
'use strict';
Note: You need to declare strict mode at the beginning of the program. If you declare strict mode below some code, it won't work.
For example,
console.log("some code");
function hello() {
hello();
If you use 'use strict'; inside a function, the code inside the function will be in strict mode.
In the above program, 'use strict'; is used inside the hello() function. Hence, the strict mode is applicable only inside the function.
As you can see, in the beginning of the program, myVariable is used without declaring.
If you declare 'use strict'; at the top of the program, you cannot use a variable without declaring it inside the function as well. For example,
function hello() {
string = 'hello'; // throws an error
}
hello();
'use strict';
'use strict';
'use strict';
hello();
'use strict';
'use strict';
'use strict';
'use strict';
'use strict';
10. You cannot also use these reserved keywords in strict mode.
implements interface let package private protected public static yield
changes previously accepted silent errors (bad syntax) into real errors and throws an error message
makes it easier to write "secure" JavaScript
What is Lodash?
A JavaScript utility library delivering consistency, modularity, performance, & extras. It provides utility functions for common programming tasks using th
functional programming paradigm.
Features of Lodash
Let us understand in detail all the important features available with Lodash :
Collections
Lodash provides various functions for collections like each, map, reduce which are used to apply an operation on each item of a collection. It provide
method like groupBy, countBy, max, min which processes collections and ease lot of tasks.
Arrays
Lodash provides various functions for arrays like to iterate and process arrays like first, initial, lastIndexOf, intersection, difference etc.
Functions
Lodash provides functions such as bind, delay, before, after etc.
Objects
Lodash provides functions to manipulate objects, to map objects and comparing objects. For example, keys, values, extends, extendsOwn, isEqua
isEmpty etc.
Utilities
Lodash provides various utilities methods like noConflict, random, iteratee, escape etc.
Chaining
Lodash provides chaining methods as well like chain, value.
In subsequent chapters, we'll cover important functions of Lodash
Step 1
As a first step, go to the official website of Lodash https://lodash.com/.
Observe that there is a download option available which gives you the latest lodash.min.js file CDN Copies available. Click on the link and select late
link for lodash.min.js.
Step 2
Now, include lodash.min.js inside the script tag and start working with Lodash. For this, you can use the code given below −
<script type = "text/JavaScript"
src = "https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js">
</script>
You can observe the following output once Lodash is successfully installed −
[email protected]
+ [email protected]
.20
added 1 package from 2 contributors and audited 1 package in 2.54s
found 0 vulnerabilities
Now, to test if Lodash works fine with Node.js, create the file tester.js and add the following code to it −
var _ = require
require(
('lodash'
'lodash')
);
var numbers = [1, 2, 3, 4];
'';
var listOfNumbers = '';
each(
_.each(numbers
numbers,
, function
function(
(x) { listOfNumbers += x + ' ' });
console.
console.log
log(
(listOfNumbers
listOfNumbers));
Save the above program in tester.js. The following commands are used to compile and execute this program.
Command
\>node tester.
tester.js
Output
1 2 3 4
Overview of Lodash :
Lodash - Array
Lodash - Collection
Lodash - Date
Lodash - Function
Lodash - Lang
Lodash - Math
Lodash - Number
Lodash - Object
Lodash - Seq
Lodash - String
Lodash - Util
Lodash - Properties
Lodash - Methods
What is Luxon?
It is a library that makes it easier to work with dates and times in JavaScript. If you want, add and subtract them, format and parse them, ask them ha
questions, and so on, it provides a much easier and comprehensive interface than the native types it wraps.
Luxon is a library for dealing with dates and times in JavaScript.
DateTime.
DateTime.now
now(
().setZone
setZone(
('America/New_York'
'America/New_York')
).minus
minus(
({weeks:1}).endOf
endOf(('day'
'day')).toISO
toISO(
();
Features
Installation Guide :
https://moment.github.io/luxon/#/install
Note : Installation Guide won’t be covered by the Instructors in the live session, students can go through the guidelines.
A quick tour
Luxon is a library that makes it easier to work with dates and times in JavaScript. If you want, add and subtract them, format and parse them, ask the
hard questions, and so on, Luxon provides a much easier and comprehensive interface than the native types it wraps. We're going to talk about the mo
immediately useful subset of that interface.
This is going to be a bit brisk, but keep in mind that the API docs are comprehensive, so if you want to know more, feel free to dive into them.
DateTime.
const dt = DateTime .local
local((2017
2017,
, 5, 15
15,
, 8, 30
30)
);
DateTime.local takes any number of arguments, all the way out to milliseconds (months are 1-indexed). Underneath, this is similar to a JavaScript Da
object. But we've decorated it with lots of useful methods.
Creating a DateTime
There are lots of ways to create a DateTime by parsing strings or constructing them out of parts. You've already seen one, DateTime.local() , b
let's talk about three more.
DateTime.
const now = DateTime.now
now(
();
This is really the equivalent to calling DateTime.local() with no arguments, but it's a little clearer.
DateTime.
dt = DateTime.fromObject
fromObject(
({day: 22
22,
, hour: 12 }, { zone: 'America/Los_Angeles'
'America/Los_Angeles',
, numberingSystem: 'beng'
'beng'}
})
Don't worry too much about the properties you don't understand yet; the point is that you can set every attribute of a DateTime when you create it. On
thing to notice from the example is that we just set the day and hour; the year and month get defaulted to the current one and the minutes, seconds, an
milliseconds get defaulted to 0. So DateTime.fromObject is sort of the power user interface.
Luxon has lots of parsing capabilities, but the most important one is parsing ISO 8601 strings, because they're more-or-less the standard wire format fo
dates and times. Use DateTime.fromISO .
DateTime.
DateTime.fromISO(
fromISO("2017-05-15"
"2017-05-15")
) //=> May 15, 2017 at midnight
DateTime.
DateTime.fromISO
fromISO(("2017-05-15T08:30:00"
"2017-05-15T08:30:00")
) //=> May 15, 2017 at 8:30
You can parse a bunch of other formats, including your own custom ones.
Now that we've made some DateTimes, let's see what we can ask of it.
toString
The first thing we want to see is the DateTime as a string. Luxon returns ISO 8601 strings:
DateTime.
DateTime.now
now(
().toString
toString((); //=> '2017-09-14T03:20:34.091-04:00'
Getting at components
We can get at the components of the time individually through getters. For example:
DateTime.
dt = DateTime.now
now(();
dt.
dt.year //=> 2017
dt.
dt.month //=> 9
dt.
dt.day //=> 14
dt.
dt.second //=> 47
dt.
dt.weekday //=> 4
dt.
dt.zoneName //=> 'America/New_York'
dt.
dt.offset //=> -240
dt.
dt.daysInMonth //=> 30
You may want to output your DateTime to a string for a machine or a human to read. Luxon has lots of tools for this, but two of them are most importan
If you want to format a human-readable string, use toLocaleString :
dt.
dt.toLocaleString(
toLocaleString() //=> '9/14/2017'
dt.
dt.toLocaleString
toLocaleString((DateTime
DateTime.
.DATETIME_MED
DATETIME_MED)
) //=> 'September 14, 3:21 AM'
This works well across different locales (languages) by letting the browser figure out what order the different parts go in and how to punctuate them.
If you want the string read by another program, you almost certainly want to use toISO :
dt.
dt.toISO
toISO(
() //=> '2017-09-14T03:21:47.070-04:00'
Immutability
Luxon objects are immutable. That means that you can't alter them in place, just create altered copies. Throughout the documentation, we use terms lik
"alter", "change", and "set" loosely, but rest assured we mean "create a new instance with different properties".
Math
This is easier to show than to tell. All of these calls return new DateTime instances:
DateTime.
var dt = DateTime .now
now(();
dt.
dt.plus
plus(
({ hours: 3, minutes: 2 });
dt.
dt.minus
minus(
({ days: 7 });
dt.
dt.startOf
startOf(
('day'
'day')
);
dt.
dt.endOf
endOf(
('hour'
'hour')
);
Set
var dt = DateTime.
DateTime.now
now(();
dt.
dt.set
set(
({hour: 3}).hour //=> 3
Intl
Luxon provides several different Intl capabilities, but the most important one is in formatting:
var dt = DateTime.
DateTime.now(
now();
'long',
var f = {month: 'long' , day: 'numeric'
'numeric'}
};
dt.
dt.setLocale
setLocale(
('fr'
'fr')).toLocaleString
toLocaleString(
(f) //=> '14 septembre'
dt.
dt.setLocale
setLocale(
('en-GB'
'en-GB')
).toLocaleString
toLocaleString(
(f) //=> '14 September'
dt.
dt.setLocale
setLocale(
('en-US'
'en-US')
).toLocaleString
toLocaleString(
(f) //=> 'September 14'
Luxon's Info class can also list months or weekdays for different locales:
Info.
Info.months
months(
('long'
'long',
, {locale: 'fr'
'fr'}
}) //=> [ 'janvier', 'février', 'mars', 'avril', ... ]
Time zones
Luxon supports time zones. There's a whole big section about it. But briefly, you can create DateTimes in specific zones and change their zones:
DateTime.
DateTime.fromObject
fromObject(({}, {zone: 'America/Los_Angeles'
'America/Los_Angeles'}
}); // now, but expressed in LA's local time
DateTime.
DateTime.now
now(
().setZone
setZone(("America/Los_Angeles"
"America/Los_Angeles")
); // same
DateTime.
DateTime.utc
utc(
(2017
2017,, 5, 15
15)
);
DateTime.
DateTime.utc
utc(
(); // now, in UTC time zone
DateTime.
DateTime.now
now(
().toUTC
toUTC(();
DateTime.
DateTime.utc
utc(
().toLocal
toLocal(
();
Durations
The Duration class represents a quantity of time such as "2 hours and 7 minutes". You create them like this:
Duration.
var dur = Duration.fromObject
fromObject(
({ hours: 2, minutes: 7 });
dur.
dur.hours //=> 2
dur.
dur.minutes //=> 7
dur.
dur.seconds //=> 0
dur.
dur.as(
as('seconds')
'seconds') //=> 7620
dur.
dur.toObject
toObject(() //=> { hours: 2, minutes: 7 }
dur.
dur.toISO
toISO(() //=> 'PT2H7M'
You can also format, negate, and normalize them. See it all in the Duration API docs.
Intervals
Intervals are a specific period of time, such as "between now and midnight". They're really a wrapper for two DateTimes that form its endpoints. Here
what you can do with them:
DateTime.
now = DateTime.now
now(();
DateTime.
later = DateTime.local
local(
(2020
2020,
, 10
10,, 12
12)
);
Interval.
i = Interval.fromDateTimes
fromDateTimes( (now
now,
, later
later));
length(
i.length() //=> 97098768468
length(
i.length('years'
'years')
) //=> 3.0762420239726027
contains(
i.contains(DateTime
DateTime..local
local((2019
2019)
)) //=> true
toISO(
i.toISO() //=> '2017-09-14T04:07:11.532-04:00/2020-10-12T00:00:00.000-04:00'
toString(
i.toString() //=> '[2017-09-14T04:07:11.532-04:00 – 2020-10-12T00:00:00.000-04:00)
Intervals can be split up into smaller intervals, perform set-like operations with other intervals, and few other handy features. See the Interval AP
docs.
Interview Questions
What do you mean by strict mode in JavaScript and characteristics of JavaScript strict-mode?
In ECMAScript 5, a new feature called JavaScript Strict Mode allows you to write a code or a function in a "strict" operational environment. In most case
this language is 'not particularly severe' when it comes to throwing errors. In 'Strict mode,' however, all forms of errors, including silent errors, will b
thrown. As a result, debugging becomes a lot simpler. Thus programmer's chances of making an error are lowered.
2. In strict mode, you won't be able to use the JavaScript keyword as a parameter or function name.
3. The 'use strict' keyword is used to define strict mode at the start of the script. Strict mode is supported by all browsers.
Imports and exports help in writing modular code for our JavaScript applications. With the help of imports and exports, we can split a JavaScript code in
multiple files in a project. This greatly simplifies the application source code and encourages code readability.
Math.
export const sqrt = Math.sqrt
sqrt;
;
square(
export function square(x) {
x;
return x * x;
}
diag(
export function diag(x, y
y)
) {
sqrt(
return sqrt(square
square(
(x) + square
square(
(y));
This file exports two functions that calculate the squares and diagonal of the input respectively.
square,
import { square, diag } from "calc"
"calc";
;
console.
console.log
log(
(square
square(
(4)); // 16
console.
console.log
log(
(diag
diag(
(4, 3)); // 5
Therefore, here we import those functions and pass input to those functions to calculate square and diagonal.