Developing Modern Web Applications

By saying Modern Web Application, Of course, I mean JavaScript. Nowadays everything about web includes JavaScript in one way or another. And this blog post I try to introduce how to develop these modern web applications with the right tools.

How it was?

Since I was an undergraduate, I have always developed on the server side and JavaScript was not as popular as it is now. Because of that when I need to develop something for client side, I was using tools which render pages on the server side like Apache Wicket or JSF. Yes, sometimes I need to use javascript or jQuery but it was a small portion of my application. When I needed a framework for responsiveness, I was either use Bootstrap or Foundation according to my design. Because of that, I had small javascript files with almost no other dependencies and I had no need for minification or modularity. Maybe I had a need for them but I was not able to realize it.

How it is now?

Let’s say I am trying to build a client side application which is consist of just javascript a.k.a VanilaJs. If I try to use the same logic as before, I will fail for sure. So I need to change my perspective.

  • I need modularity: If I try to use a single JS file for my whole application, I probably cannot even finish my application. I need to divide my app into the smaller javascript files. Maybe even, I need to use TypeScript or Coffee Script in order to increase reusability and modularity. To be able to use these supersets of javascript, my development environment must support compiling TypeScript to the JavaScript (EcmaScript5).
  • I need to minify: I cannot expect my user to load a whole file without minifying it. I t may take ages. I need to minify my javascript files in order to decrease load time of my application.

    jquery-2.1.3.js is 247 KB, but jquery-2.1.3.min.js is 84 KB.

  • I need to use CDN: I may use minified versions of my own javascript files. But it is not a best practice for my client-side dependencies. It is better to use CDN addresses. My development environment must be able to download my client-side dependencies and also can convert them to CDN versions. By using CDN versions, usage of browser cache will be maximized.

On the other hand, as a Developer, I have other needs for my developer environment in order to deliver high-quality product. Such as:

  • There is no standard structure for javascript project. In order to maximize productivity, I need to specify my default project structure to manage it well.
  • I need a tool to build my TypeScript or CoffeScript to JavaScript.
  • I need a tool to manage my client-side dependencies. Let say, I’m trying to develop an Angular.js application. I will need, Angular.js and some of its modules. There must be a tool to manage this dependency.
  • I must be able to write unit and functional tests. Also, I must be able to run my tests almost all of the browsers to be sure that my application working correctly on every platform.
  • There must be a Codding Convention or Naming Convention for my JavaScript or TypeScript files. I may be from Java world, but I do not want to write a JavaSciprt application like a Java developer. I want to write a JavaScript application like a JavaScript developer. So I must be able to apply common rules to my application.

tl;dr $ npm install -g yo grunt-cli bower generator-angular && yo angular

Also, let me clear that out, these tools and structure is best for my development perspective. There are many other alternative ways to reach same goals.

Development Environment

Development environment is on top of node.js platform as you may guess. Although node.js is for developing server-side application using javascript, It easily became the best development environment for javascript.

Node.js has been one of the most trending topics since many years. A lot of tools were developed just for node.js development. Almost all of it can be used for client-side development. And as you may guess there are numerous alternatives for each tool that I mention in this post.

If you do not install or try node.js before you can download it from this link. After the installation, you have two new command line tool.

  • node: This command can execute server-side javascript files. This is a topic for another blog post.
  • npm: As I said earlier our development environment is node.js. But node.js is like our runtime environment. All the tools we will use runs on the top of node.js. So, how we install our tools to top of node.js? We will use npm command to install them. While discussing our tools I will describe how to install them using this command.

Yeoman and Project Structureyeoman

Our first tool is Yeoman that is scaffolding tool for javascript application. It creates a project for you. You must select your generator through his catalog and let him generate your application for you. This way you automatically have a default project structure.

From a Java perspective, Yeoman is like maven’s archetypes.

First you need to install Yeoman. In order to do that you need to execute this command:

$ npm install -g yo

After that, you need to select your generator. As we discussed earlier, we will develop an Angular.js app. So we will use a generator for angular.js.

$ npm install -g generator-angular

And lastly, we need to tell yeoman to create our application using angular.

$ yo angular

After this point, Yeoman will ask you questions about your generator. You can select either using Bootstrap or not or you may want to us Saas compiler. It is up to you. I use default settings expect Saas compiler. I do not want to use a Saas compiler for my project.

Let me try to explain each generated files briefly.

  • .bowerrc: Connection and other types of configuration will be defined here for Bower
  • .editorconfig: EditorConfig is a tool for formatting JS files in editors(SublimeText etc) and IDEs(WebStorm, Intellij, etc).
  • .gitattributes: GIT Configuration file
  • .gitignore: GIT ignore file
  • .jshintrc: As I mentioned earlier, there must be a coding and naming convention. This file contains configurations about these conventions. JsHint is a plugin for Grunt.
  • .travis.yml: Travis is Continuous Integration platform. This file holds the configuration about that platform.
  • app/ : All our Angular.js files are defined in this folder.
  • bowercomponents/ : Bower manages our client-side dependencies. Bower downloads all the client-side dependencies to this folder.
  • dist/ : When we build our application, our final javascript files will be in this folder.
  • nodemodules/ : NPM installs all the development dependencies to this folder.
  • test/ : All our test files and configurations are under this folder.
  • Gruntfile.js : Grunt is a task runner tool. All the grunt tasks are defined in this file.
  • bower.json : In order to Bower install our client-side dependencies, we must define them in this file.
  • package.json : In order to NPM installs all the development dependencies, we must define them in this file.
  • Project Readme file.

As you can see, all the details are well defined.

Bower and Client Side Dependenciesbower

Bower is responsible for managing our client-side dependencies. But we
need to install it first. In order to do that we must execute this command:

$ npm install -g bower

After installing bower, we can run these commands from the terminal.

  • $ npm install -g bower: Installs dependencies which are defined in bower.json
  • $ bower install [package_name]: Installs dependencies which are not defined in bower.json
  • $ bower install [package_name] –save: Installs dependencies which are defined in bower.json and adds that dependency to the bower.json
  • $ bower init: Creates a bower.json files interactively

From a Java perspective, Bower is like Ivy or Maven’s Dependency Management

Grunt and Task Managementgrunt

Grunt is one of the most used task management tool for node.js environment. All you have to do is installing your Grunt and its plugins trough npm and define your tasks in Gruntfile.js. All the plugins that are used by Grunt are already defined in package.json file. And after you install your application by executing this command Grunt and all of its plugins are
automatically installed.

$ npm install

Ok, now we install grunt. But before start to using it, let’s discuss a little for what purpose we will use it

  • Executing Tests: Grunt executes all the tests (we will use Karma and Jasmine to running and defining our tests).
  • Running a Development Server: Grunt runs a web server for our static files like HTML, JavaScript, and CSS so we can develop our application without any other dependencies.
  • Minified-Uglified: Grunt can minify our files using plugins.
  • Compiling Saas or Less: Grunt can compile SAAS or LESS files to CSS files.
  • Compileing TypeScript or CoffeScript: Grunt can compile supersets to the JavaScript (EcmaScript5) using plugins.
  • Checking Coding and Naming Conventions: Grunt will check our conventions by using plugins.

If you read our generated Gruntfile.js, you can see that we have many tasks and tasks groups to run. Some of the important task groups are explained down below.

  • $ grunt build: Builds you project. Merges all your javascript file to one javascript file and minifies it.
  • $ grunt test: Executes your tests using Karma and Jasmine.
  • $ grunt serve: Runs a web server for your development environment with a LiveReload and Watch ability. This means, if you change any file, they will be reloaded automatically.

From a Java Perspective, Grunt is like Ant.

Define and Run Testskarma_jasmine

Karma and Jasmine are used for testing. Development dependencies for these tools are defined in the package.json file and can be installed through npm by executing this command.

$ npm install

Let me try to explain why we need two different tools for testing. As you can guess our application will be run on a browser. This means our development environment and runtime environment are completely different. So we need to run our test on a platform. Karma is providing us this environment. On karma configuration file (test/karma.conf), we must define which browsers will be used for test. You can use headless browser simulators like Phantom.Js or you can use Chrome or Firefox.

After configuring Karma, you need to define your tests using Jasmine. The code you will write using Jasmine is going to be executed by the browser that is defined in Karma. One test can be run on different browser through Karma configuration.

From a Java perspective, Jasmine is like Junit but there is no equivalent for Karma

Develop JavaScript App Like a JavaScript Developer

I ensure you, It is not as easy as it sounds. It is hard to leave your habits from Java. I started by reading google style guides, which are given down below.

End of Line


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s