With plain JavaScript we can do a lot of things. However, there’s no set structure or if we write plain JavaScript code, so developers need a lot of discipline to structure their code properly. This takes a lot of effort and so it wastes a lot of developer’s time enforcing structure of every part of the code.
Manipulating the DOM is also very fragile because in today’s web apps, there are way too many things going on which can change the DOM. This means that elements appear and disappear in indeterminate amount of times. This create issues since we might be trying to manipulate DOM elements that aren’t there yet. Or multiple pieces of code might try to modify the same element at the same time.
It’s just too difficult to troubleshoot those issues and get your code working correctly. This means that a lot of time on these little issues, which takes away developer’s time that can be used to develop features. This is where frameworks come in to save the day.
Frameworks provide structure which allows teams of developers to develop complex web apps in a structured way. Most frameworks enforce their own conventions so structures can be enforced if multiple developers develop the same application. DOM manipulation is abstracted away in frameworks so that developers do not have to worry about that unless they develop features that need direct DOM manipulation like animations.
Libraries are small pieces of code that we can include in our app’s code to extend the functionality of our apps. Libraries make add functionality easier and some also provide shortcuts that does the equivalent of what’s available in plain JavaScript but better. There are also libraries that are made for specific frameworks to enhance their functionality.
Vue.js
Vue.js is a component based front end JavaScript framework that lets developers create high quality maintainable web apps in an easy way. The framework lets developers divide their app into Vue.js components, which are self contained parts that when put together, we get a full web app. Components are made to be nested within each other. Each component has a template for rendering the data, a script section for the logic, and a styles section for the CSS styles. Component support data binding between the template and script sections which means that changes from the template section is automatically reflected in the script section and vice versa. Each component has its own life cycle and has function to handle those life cycle events. Parent components can pass data into child components and child component can emit events to pass components into the parent.
With Vue.js, DOM manipulation is done in the background by getting the difference between the browser DOM and the virtual DOM tree it creates and make the changes from the virtual DOM to the actual DOM.
Also there’s a built in URL router called the Vue Router that lets developers map specific URLs into the pages of their apps. For centralize state management it uses the Vuex flux library which lets us use the flux architecture to store the app’s state centrally. Flux architecture basically means that data are set in a central data store and then components that need the data always get the latest data from the store by observing the values from the store.
New apps usually use the Vue CLI to create the project and select what to include.
Other feature it supports out of the box includes testing, CSS preprocessors like SCSS and SASS to make writing complex CSS easier, and building to web components or progressive web apps, and other advanced features. It can also be added incrementally to legacy web apps by using script tags. The Vue.js framework and libraries made for Vue.js all support this. So it’s a great choice for upgrading the functionality of legacy web apps.
There’s large ecosystem of libraries that we can use with Vue.js applications including component libraries, helper modules geolocation and webRTC modules and many others.
Angular
Like Vue.js, Angular is a component based framework. It’s made by Google. Most of the things that’s part of the Vue.js feature set is also in Angular, except the state management part. By default, Angular applications are written in TypeScript he framework lets developers divide their app into Angular components, which are self contained parts that when put together, we get a full web app. Components are made to be nested within each other. Each component has a template file for rendering the data, a TypeScript file for the logic, and a styles file for styling, which can be CSS, SASS or SCSS. Also, there’s a test file to add your unit tests for each component. Component support data binding between the template and script sections which means that changes from the template section is automatically reflected in the TypeScript file and vice versa. Each component has its own life cycle and has function to handle those life cycle events. Parent components can pass data into child components and child component can emit events to pass components into the parent.
Many parts of the library uses reactive programming, which means that parts of the app watches for data changes and does something when it changes. This is done mainly with observables.
One unique feature of Angular is that it includes dependency injection so that we don’t have to worry about resolving the dependencies of Angular libraries ourselves, which saves a lot of headaches since most web apps probably lots of dependencies.
Angular apps are divided into modules, which we can combine into one to make one whole app. Each module include the libraries that are needed to be used by that module.
With Angular, DOM manipulation is done in the background by getting the difference between the browser DOM and the virtual DOM tree it creates and make the changes from the virtual DOM to the actual DOM.
Also there’s a built in URL router called the Angular Router that lets developers map specific URLs into the pages of their apps.
Other feature it supports out of the box includes building to web components or progressive web apps, and other advanced features. There’s large ecosystem of libraries that we can use with React applications including component libraries, helper modules like NgRx store for state management many others.
React
React is a component based library that we can use to make dynamic web apps. It uses the JSX syntax for writing JavaScript which looks like HTML, except that you can mix it with JavaScript directly. Each component has its own life cycle and has function to handle those life cycle events. It also provides nesting for components and also allow for higher order components, which are components that returns component. There are 2 kinds of components in React. One is class based components, which are written as a class, with a render
method at the end to render the HTML. The other is function components which returns the JSX directly and rendered into HTML. Originally function components cannot have dynamic logic, but now that React has hooks, function components can also have logic code in it.
With React, DOM manipulation is done in the background by getting the difference between the browser DOM and the virtual DOM tree it creates and make the changes from the virtual DOM to the actual DOM.
It does not include anything other than a view library to render JavaScript into HTML, so if we want to build a full single page application, we need to add other libraries like React Router and a state management like Redux. There’s large ecosystem of libraries that we can use with React applications including component libraries, helper modules like React Router and Redux and many others.
Lodash
Lodash is a library which contains many handy methods for manipulating data. Examples include array methods like flatten
to squash a nested array into an ordinary array. There’s also a flattenDeep
to flatten all levels of a nested array into a flat array. Other functions include:
findIndex
— find the index of a given objectfindLastIndex
— find the last index of a given objectpull
— removes the first given item from the arraypullAll
— remove all the given item from the arrayreverse
— reverse an arraysortedIndex
— get the index to insert the given item so that the array stays sortedget
— function used to traverse an object to get the item with the given property and return null if it can’t traverse the object to get the item or if it’snull
orundefined
There are many more functions that aren’t yet available in plain JavaScript, even though some like find
and findIndex
did make it into JavaScript’s standard library, so Lodash is still useful.
Moment.js
Manipulating time and date in JavaScript is painful. Even with the functions available with Date
objects, there are plenty of chances of bugs and errors. Also, there are no functions for formatting times and dates which is a big problem. To solve this, we use moment.js. This is the best library available for dealing with time.
There were issues with time zones with YYYY-MM-DD dates being parsed into UTC time as opposed to local time. Which creates bugs for developers who aren’t aware of this problem. See https://stackoverflow.com/questions/29174810/javascript-date-timezone-issue
Also there are difference in support for parts of Dates in different browsers. (See https://stackoverflow.com/questions/11253351/javascript-date-object-issue-in-safari-and-ie)
It is also hard to add and subtract timestamps with built in Date functions. There is no way to do this without writing a lot of code and doing a lot of checks. Also, there is no way to compare 2 times.
Formatting dates is also not available without writing your own code for using third party libraries.
Moment.js solves all of these issues by providing built in functions to do all these common operations. It provides functions for parsing and formatting dates.
The moment
constructor is where you can pass in a date string, and a moment
object will be created. For example, you can pass in:
moment('2019-08-04')
and you will get back a moment
which you can compare with other moment
objects, and add or subtract by different time spans.
If you do not passing in anything to the moment
constructor, you get the current date and time.
It also takes a second argument. If you want to make sure a date is parsed as a YYYY-MM-DD date, then write moment(‘2019–08–04’, 'YYYY-MM-DD')
. If you don’t know the format of your date or time, then you can pass in an array of possible formats and Moment will pick the right one:
moment('2019–08–04', ['YYYY-MM-DD', 'DD-MM-YYYY']);
After you create a Moment object, then you can do many things like formatting dates:
const a = moment('2019–08–04', 'YYYY-MM-DD').format('MMMM Do YYYY, h:mm:ss a');
console.log(a);// August 4th 2019, 12:00:00 am
const b = moment('2019–08–04', 'YYYY-MM-DD').format('dddd');
console.log(b);// Sunday
const c = moment('2019–08–04', 'YYYY-MM-DD').format("MMM Do YY");
console.log(c);// Aug 4th 19
const d = moment('2019–08–04', 'YYYY-MM-DD').format('YYYY [escaped] YYYY');
console.log(d);// 2019 escaped 2019
const e = moment('2019–08–04', 'YYYY-MM-DD').format();
console.log(e);// 2019-08-04T00:00:00-07:00
From the above examples, we see that we can format dates in pretty much any way we want.
We can also tell what time span a date is relative to another date by writing:
const augDate = moment('2019–08–04', 'YYYY-MM-DD');
const sepDate = moment('2019–09–04', 'YYYY-MM-DD');console.log(augDate.from(sepDate)); // a month ago
We can also add or subtract Moment dates:
const augDate = moment('2019–08–04', 'YYYY-MM-DD');
const sepDate = moment('2019–09–04', 'YYYY-MM-DD');console.log(augDate.add(10, 'days').calendar()); // 08/14/2019
console.log(augDate.subtract(10, 'days').calendar()); // 07/25/2019
It is easy to compare 2 dates
moment('2010-01-01').isSame('2010-01-01', 'month'); // true
moment('2010-01-01').isSame('2010-05-01', 'day'); // false, different month
moment('2008-01-01').isSame('2011-01-01', 'month'); // false, different year
You can also check if a date is has Daylight Saving Time in effect or not:
const augDate = moment('2019–08–04', 'YYYY-MM-DD');
const decDate = moment('2019–12–04', 'YYYY-MM-DD');
console.log(augDate.isDST()) // true
console.log(decDate.isDST()) // false
And you can convert back to JavaScript date any time by calling the toDate()
function on a Moment object.
As we can see. There’re lots of things that Moment.js can do that can’t be done in plain JavaScript, so we need this library badly.
All in all, developing front end JavaScript web apps feels almost like magic with all these libraries and frameworks. It makes development a lot easier if you’re working alone and in teams. There’s no way to live without all these modern day libraries and frameworks. A lot of these things that frameworks and libraries do aren’t possible with plain JavaScript.