How to Effectively Develop Vanilla Javascript Application
Why Vanilla JS - Plain Simple Javascript
What comes to your mind when you are asked to develop a front-end application? This is a big question, because the JS world changes frequently and new technologies are being invented at the speed of light. Well, that could be an exaggeration ...but the truth is that choosing an approach to develop a front-end application can be tough, as we have so many options! Choosing an approach becomes even more important and requires greater responsibility if we're asked to work on an enterprise application. For any application, you need to ensure that development is easy and scalable. But remember, it has to go to production too, so it should be performant and lightweight.
When we take a good framework like Angular or React, we get a great development process as well as very performant applications. Additionaly, we also get applications that scale well. But sometime the most important thing for a web app is to load fast, even on the first load. For this reason, we can choose Vanilla/Plain JS without any framework or heavyweight libraries. When taking a decision, you should consider these three factors:
- Maintainability of code
- Scalability of code
- Compatibility with the latest approach (i.e. using PWA for making our web app)
If these specifications are met, you would enjoy coding even if it is just plain javascript. I will try to address some issues that developers might face while developing an application with plain javascript.
Vanilla JS - Issues addressed
Here are few of the concerns we want to address when we're developing a good vanilla JS application:
- Maintainability of code
- Scalability of code
- Flexibility of code
- Making PWA apps with Vanilla JS
To solve these issues, we should structure our application so that:
- App is modular
- App is using latest technologies, i.e. ES6
- App should not load too much on the browser (initial load should be 5 kb and the app shell should not exceed 50 kb)
- App should be performant
There are two approaches to my knowledge:
-
Use polymer: Polymer is a library and it is not a heavy framework. It prvides you a simple way to make web components. Polymer's development standard fully follows PWA guidelines. It gives you full freedom to choose your own libraries for stuffs like routing, promises, etc.
-
For second approach - Please read rest of the article and write code with Vanilla JS.
Using Vanilla JS - The 2nd Approach
Ok, let's jump right into the technologies that are required to build the app:
- A great build tool β my choice is Webpack.
- Something that lets you write ES6 β my choice is Babel.
- Some modular system to make your app flexible and scalable β my choice is ES6 modules.
- Do more compilation at server/build end, rather than assigning your browser to perform heavy tasks β I use Babel compiler with lodash to compile most of my code at build time. Webpack wires up everything and outputs small files.
- Make initial HTML small and lazy load your app shell. (What I mean by "app shell" is a file that loads most of the code of your app.)
- Take minimum time to develop β I use Webpack dev server with Hot Module Replacement feature. It saves a lot of time. You can also use Webpack DLL plugin.
- Try to make at least 3 other JS files during build process instead of including everything in app shell β I build
common-chunks.js
,library.js
, andpolyfill.js
file along withapp-shell.js
bundle. - Always use cache busting mechanism β Webpack provides this.
- Use service workers - I use node modules, provided by the Google Chrome team on their GitHub page.
- Modularity is not only applicable for Javascript, but also to our HTML and CSS. I use EJS for HTML and SASS for CSS.
Let's discuss them one by one briefly.
Good Build Tool - Using Webpack
Webpack is a great build tool for JavaScript. It provides almost everything you may want from your build tool. The best thing is that it reads everything as a JavaScript module. You can find hundreds of tutorials for webpack online - here's a good one. It's worth highlighting 3 of the most important things in webpack:
- input/output feature: The input means your entry points and output means your build file.
- loaders: Loaders are used to make non js modules into js modules.
- plugins: Plugins parse all javascript in some useful way.
Other build tools could be gulp, grunt or broccoli. Of course, you can also write your own node modules for this purpose (the only problem is wiring up all your tasks and build processes). If not Webpack, my second choice would be gulp.
ES6 - Using Babel
Every JavaScript community has hot topics surrounding ES6/ES2015 features. Everybody loves it. The only problem is that browsers are not fast enough to adopt it. This problem can be solved by some good ES6 compiler. The best one out there is Babel. It provide a lot of features. There is also a babel-loader that compiles all your ES6 code into ES5 code through webpack.
For runtime ES6 interpretation, you can use Babel-polyfill, core.js or babel-runtime during build time for modular purposes.
Another option is Traceur, which is only executed in browser during runtime. I don't like it very much for the same reason.
A good alternative would be Typescript + Core.js. However, you will have to learn typescript first which is another overhead.
Modules for Javascript
There are many different modules you can develop for JavaScript files. Some existing module systems include commonJS, AMD, and UMD. UMD is a combination of commonJS and amd; therefore, it's best to make your js files as UMD modules. Keep in mind that writing UMD module is a difficult and time taking task. Webpack can solve this problem!
Does this mean I shouldn't write anything to make it modular? No, that's not what I meant. Any js file in webpack is a module, mostly UMD module, but you can specify the exports of any file. I follow the ES6 module writing approach because it is very straightforward.
To export a variable from a file 'foo.js', write:
export var myFoo = function(greeting) {
return `${greeting} to Foo`;
}
To use it inside a bar.js
file, write:
import {myFoo} from './foo.js'
console.log(myFoo("Welcome")); //output will be - "Welcome to Foo"
Do More Compilation at Built Time
Webpack, with its loaders and plugins, will provide you all the tools to do compilation at built time.
Some of my favorite plugins are: CommonsChunkPlugin
, HtmlWebpackPlugin
, ExtractTextPlugin
, etc.
Here are some very useful loaders: html-loader
, style-loader
, css-loader
, sass-loader
, ejs-loader
, pug-loader
, babel-loader
, file-loader
, url-loader
, etc.
Make Initial HTML Small and Lazy Load Your App Shell
Write less in your initial HTML and lazyload the rest of your app. Everyone's need may vary, depending on the kind of application he/she is building. Try to follow the PWA approach no matter what.
Take Less Time to Develop
Use outstanding development server and use mock data for development. I use webpack-dev-server for loading my development environtment. It live realoads browser and it can limist the module it injects to those that has been changed or updated in development environment.
Try to use the 'process.env.NODE_ENV' variable as much as you can to differentiate between what needs to be shown during development and what should be included in production build.
Use HMR module of Webpack if you are using Webpack to inject your changes rapidly in your browser during development.
Additionally, use some mock data server to mock your actual backend services. For that, I use json-server with a json db and routes.json file.
A good replacement for webpack-dev-server could be lite-server, which is available as a NPM module and includes Browser sync for live reload feature.
Use Service Workers
I use service workers mostly to make my application offline. However, there are many other use cases of service workers. Please read this google developer article for more information.
Please use this node module for making your application offline.
Modularity for HTML and CSS
I will cover two important aspects of HTML and CSS development: making them modular and making them programmable.
When I say I want to make something programmable, it means that I want myself to be able to apply logic, do calculations, use variables, make it configurable, etc.
-
For CSS, I choose SASS. It makes things modular and configurable. You can declare variables and write conditions, mixins, and functions.
Make sure to install node-sass and sass-loader for Webpack in order to use SCSS files.Alternatives to SASS include LESS and Stylus.
-
For HTML, I use EJS. The main reason is that I can use EJS alongside my normal HTML very easily. I don't need to change my normal HTML and I can still integrate EJS into it. Also, EJS can be compiled at build time and it can also be interpreted at runtime. Using normal js varibales through interpolation (both ES6 way and EJS way) is really easy when you have a webpack-babel project.
With EJS I can make my EJS files(view files) truly modular and pass variables that can be used inside template. Making modular HTML(views) provides us a great way to develop a component based application in Vanilla Javascript project.
Other options include Jade/Pug, handlebars, Haml, etc.
Time to Use These Concepts
This is it guys, I hope you liked this article. I tried to keep it as compact and as simple as possible. Hope it was helpful. Please feel free to write your own JS application using this article as a guideline β I'm sure you'll get a hang of it very soon! Also please comment and share your opinions.
Thanks for reading.
I am always available on Codementor! Please feel free to reach out to me if you have any questions!
Hereβs the middle ground - https://github.com/vitaly-t/excellent
Thatβs using Vanilla JS, but with efficiency.
This Stuff is really great. As you said that For any application, you need to ensure that development is easy and scalable. But remember, it has to go to production too, so it should be performant and lightweight. I am fully agree with that to do this course Visit Koenig Solutions
π