Search icon
Arrow left icon
All Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletters
Free Learning
Arrow right icon
Data Oriented Development with Angularjs

You're reading from  Data Oriented Development with Angularjs

Product type Book
Published in Apr 2015
Publisher
ISBN-13 9781784398057
Pages 156 pages
Edition 1st Edition
Languages

Appendix A. Yeoman

Today Node.js (available at http://nodejs.org/) needs no introduction, but for the benefit of those who haven't crossed paths with it yet, here's an introduction—Node.js lets developers write server-side code in JavaScript. Yes, it's the same JavaScript, which used to run only in browsers until a few years ago. The same JavaScript, which was confined to the frontend, was suddenly unleashed on the world of backend which was previously accessible to server-side languages such as Java, C#, Ruby, Python, and the like.

Note

Consequently, you can access the filesystem, write data-intensive applications which access relational DBs or NoSQL DBs, write a web server with Node.js, and so on.

Previously, for doing anything with the Web, developers were supposed to learn and write code in at least two different languages—a server-side language and JavaScript. Node.js changed this and made our lives easier because the frontend and the backend code can be written in the same language now.

It is said that for a programming language to gain mass adoption, it needs a successful and famous library/framework. For example, Rails did it for Ruby. Node.js is doing the favors for JavaScript—so much so that this survey (available at http://adambard.com/blog/top-github-languages-for-2013-so-far/) pegs JavaScript as the top language for 2013, based on the number of repositories created on GitHub.

Now when we start coding in any language, we typically use an IDE-like Visual Studio for .NET and maybe Eclipse for Java, or we might use powerful text editors such as Sublime Text or Emacs. The extra work these IDEs do for us is to generate a project skeleton when we create a new project. However, the text editors lack this support because they are not programming language-specific. So what do we do when we are starting a new Angular project? Surely, we can create a project structure manually, but it wouldn't be too productive, right? Then we would have to do this cumbersome activity again for any new project we create. Also realize that typically, there are three activities required in a project of reasonable complexity, irrespective of the programming language, where automation could help developers:

  • Scaffolding: The dictionary meaning of a scaffold is a temporary structure for holding workers and materials during the erection, repair, or decoration of a building. So, scaffolding in programming terms means generating an agreed upon (based on the best practices for that language or framework) folder structure for us.

  • Dependency management: Any sufficiently complex project has to use external libraries/frameworks, and in this day and age, we can't be expected to manually download the DLLs, JAR files, or JavaScript/CSS files and manually include them in the correct path.

  • Build management: Once we are done with the development, we need to build the source code and possibly package it as an EXE, JAR file, or a minified JavaScript file.

This is where the tools, which we are going to discuss in the next section, such as NPM or Yeoman come handy.

NPM


Any modern programming language has a package manager for managing external dependencies in your program. In simple terms, it means downloading and using various external libraries/frameworks in your program; for example, Clojure has Leiningen (available at http://leiningen.org/), Ruby has RubyGems (available at https://rubygems.org/), and .NET has Nuget (available at https://www.nuget.org/). NPM (available at https://www.npmjs.com/) is the official package manager for Node.js. NPM is bundled with Node.js these days, so as soon as you install Node.js (for your OS), NPM is ready to serve you.

You might think that you are just developing an Angular application and you don't plan on writing server-side JavaScript (or using Node.js), so why do you even need NPM? The answer to your quandary is that NPM is required to install the other tools mentioned in the next sections, and it's needless to say that you'll thank yourself for installing Node.js and NPM.

Yeoman


As far as I remember, I came across the term scaffolding (available at http://en.wikipedia.org/wiki/Scaffold_(programming)) while reading about Ruby on Rails framework. Scaffolding generates the boilerplate code for us, thereby reducing the grunt work we have to do. For example, it might generate a controller, some views, and the database table based on a model; or it might generate an agreed upon (based on the best practices for that language or framework) folder structure for us at the start of a project.

Yeoman (available at http://yeoman.io/) is a scaffolding tool for writing modern web applications. It is available as an NPM package, so you can install it globally (for a machine) using NPM as follows:

npm install –g yo

The Yeoman workflow comprises of three tools (which help us automate the three required tasks as discussed previously):

  • yo: This tool scaffolds out a new application

  • grunt or gulp: These are the build tools

  • bower: This is the package manager

Yeoman also provides a generator ecosystem. As per the Yeoman website, "A generator is basically a plugin that can be run with the yo command to scaffold complete projects or their useful parts." So, for example, there are generators for scaffolding an AngularJS, Backbone, or Ember application. The different generators available are listed at http://yeoman.io/generators/.

You can install the Angular generator using the following command:

npm install -g generator-angular

Once this is installed, there are commands for generating an Angular controller, directive, view, service, and so on. Let's generate a new Angular application now. Make a new directory and cd into it and run the following command:

yo angular bookExamples

When we run the preceding command, we are asked to choose from several options such as whether we want to use Sass (with Compass) or include Bootstrap, and then we are asked to choose between different modules (as shown in the following screenshot). So you can see the choices I made here (an (*) symbol means you need to include the module, otherwise exclude it):

After making our choices, when we press Enter, the angular generator generates a directory structure which looks as shown in the following two screenshots. The preceding command also runs bower install and npm install internally (which we can also run separately).

Notice the following important points about the first screenshot:

Folders and files generated by the yo angular command.

The root folder has the app, node_modules, and test folders.

The app folder has scripts, views, and styles folders.

The scripts folder has a controllers folder.

The root folder also has the bower.json, Gruntfile.js, and package.json files.

Let's look at the contents and purpose of some of the preceding files:

{
  "name": "book-examples",
  "version": "0.0.0",
  "dependencies": {
    "angular": "^1.3.0",
    "bootstrap": "^3.2.0",
    "angular-cookies": "^1.3.0",
    "angular-resource": "^1.3.0",
    "angular-route": "^1.3.0"
  },
  "devDependencies": {
    "angular-mocks": "^1.3.0"
  },
  "appPath": "app",
  "moduleName": "bookExamplesApp"
}

(bower.json)

As you know by now bower is a dependency management tool, so this JSON file lists all the dependencies under the dependencies key. There are some dependencies like the one on angular-mocks, which are only required during development (which we don't ship), so they are grouped under the devDependencies key. Also notice that the name of the main module is bookExamplesApp as specified by the value of the moduleName key in the preceding table. Please remember that we ran the angular-generator using the bookExamples value. Let's check the contents of the .bowerrc file, as shown in the following code:

{
  "directory": "bower_components"
}

(.bowerrc)

This file specifies the folder where bower dependencies should be placed. So as shown in the preceding file, the bower dependencies are stored in the bower_components folder. Let's look at a part of the package.json file:

{
  "name": "bookexamples",
  "version": "0.0.0",
  "dependencies": {},
  "repository": {},
  "devDependencies": {
    "grunt": "^0.4.5",
    "grunt-autoprefixer": "^2.0.0",
    "grunt-contrib-cssmin": "^0.12.0",
    "grunt-contrib-htmlmin": "^0.4.0",
    "grunt-contrib-imagemin": "^0.9.2",
    "grunt-contrib-jshint": "^0.11.0",
    "grunt-contrib-uglify": "^0.7.0",
    "grunt-contrib-watch": "^0.6.1",
    "grunt-karma": "^0.10.1",
    "grunt-ng-annotate": "^0.9.2",
    "grunt-svgmin": "^2.0.0",
    "jasmine-core": "^2.2.0",
    "karma": "^0.12.31",
    "karma-jasmine": "^0.3.5",
    "karma-phantomjs-launcher": "^0.1.4",
    "load-grunt-tasks": "^3.1.0",
    "time-grunt": "^1.0.0"
  },
  "engines": {
    "node": ">=0.10.0"
  },
  "scripts": {
    "test": "grunt test"
  }
}

(package.json)

This file again lists dependencies and devDependencies, and these dependencies are for various npm modules.

Bower and NPM are both used for managing dependencies. However, Bower manages dependencies for the frontend libraries/components (such as Bootstrap, UnderscoreJS, and so on) whereas NPM does the same for various Node.js modules.

Take a look at the second screenshot shown here:

Files and folders for unit testing generated by the yo angular command.

The root folder has a test folder.

The test folder has a spec folder, and the spec folder has a controllers folder.

The test folder also has a karma.conf.js file. Karma (available at https://github.com/karma-runner/karma) is a test runner for JavaScript and can run tests written in Jasmine (available at http://jasmine.github.io/), Mocha (http://mochajs.org/), and so on.

For any UI application, we can write two types of tests—unit tests and end-to-end (E2E) tests, where the tests actually spin up a UI and interact with it as a user would. For the unit testing Angular code (available at https://docs.angularjs.org/guide/unit-testing), we can use any of the existing JS unit test frameworks such as Jasmine, Mocha, and so on. However, for E2E testing (available at https://docs.angularjs.org/guide/e2e-testing), Angular recommends Protractor (available at http://angular.github.io/protractor/#/), which uses Jasmine for its test syntax. Once we have written the tests, we need a test runner which can run these tests. A good test runner is one which can be configured to run automatically (from continuous integration scripts). So, Karma is the recommended test runner for Angular applications.

Grunt


Grunt is a JavaScript task runner. It automates common tasks such as minification, compilation, linting, unit-testing, and so on. We need to create a task file to instruct the test runner to automatically take care of such mundane tasks.

Gulp is described as a streaming build system. It is used as an alternative to Grunt, whereas Grunt relies on configuration over code (meaning the tasks are specified as JSON configuration), Gulp takes the other approach, that is, code over configuration which means various tasks are configured in code.

It's best to install Grunt CLI (command-line interface) using the following code:

npm install –g grunt-cli

Now you can run Grunt from any folder and run the following code:

grunt --help

Note

There's a well-known Unix convention for using command-line arguments by which you can either use the full name of the argument preceded by two dashes -- or by using a single letter abbreviated name of the argument preceded by a single dash -. So the preceding command may also be run as follows:

grunt -h

But not all the command-line applications follow this convention.

Now you'll see that there are many grunt tasks available such as clean (for cleaning files and folders), cssmin (for minifying CSS), and htmlmin (for minifying HTML).

Let's take a look at a part of the gruntfile.js, as shown in the following table:

grunt.registerTask('serve', 'Compile then start a connect web server', function (target) {
    if (target === 'dist') {
      return grunt.task.run(['build', 'connect:dist:keepalive']);
    }

    grunt.task.run([
      'clean:server',
      'wiredep',
      'concurrent:server',
      'autoprefixer:server',
      'connect:livereload',
      'watch'
    ]);
  });

(gruntfile.js)

The preceding file shows a task called serve, which is used to run the application. This task compiles the application, starts a web server, and then launches the default browser with the application running. So let's check it out by doing the following action:

grunt serve

Now you'll see an application similar to the one shown in the following screenshot:

Running application generated by yo angular.

In the preceding screenshot, the name of the application is highlighted; we specified the name of the application as bookExamples when we ran yo angular (as the first argument to this command).

Similarly, the grunt build command minifies the CSS and JS files and updates the references to external libraries from the bower_components folder to their CDN versions, and the grunt test task runs the unit and E2E tests using Karma.

Bower


Just like we use NPM for managing Node.js modules (which are stored in the node_modules folder), we use Bower (available at http://bower.io/) for managing dependencies on the frontend (which are stored in the bower_components folder). Suppose you want to use UnderscoreJS (available at http://underscorejs.org/), you can install it using the following command:

bower install underscore

This will download underscore in the bower_components folder, but it doesn't make changes to the bower.json file. However, we want that if any other team member pulls the latest source code, he too should get a copy of underscore on his machine. So we can run the following code:

bower install underscore --save

This adds an entry for underscore in the dependencies section of the bower.json file. However, if we want to install it as a dev-dependency, we need to run the following code:

bower install underscore --save-dev

This adds an entry for underscore in the devDependencies section of the bower.json file.

Note

There are certain packages which we need only during development; for example, unit or mock testing libraries or even grunt itself. We don't want to ship any of these to the client. Consequently, both package.json and bower.json files have dependencies and devDependencies sections. The devDependencies section contains names of packages needed only during development.

lock icon The rest of the chapter is locked
You have been reading a chapter from
Data Oriented Development with Angularjs
Published in: Apr 2015 Publisher: ISBN-13: 9781784398057
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime}