This post is not a tutorial on Angular js
there are a lot of them online and i would recommend you check them out. This is more about the setup of Angular js
so you can build apps that are easy to maintain in the long run and manageable.
grunt
and browserify
If you have worked with something like ember.js
you might have noticed that how everything is just in the right folder and it comes out of box with live reload etc. The same is not the case with angular and therefore many people end up doing it wrong. Let us start with creating a package.json
to maintain all dependencies
npm init --yes
Now assuming that you have installed grunt-cli
globally here is what you do next. Install packages that you would be needing for live reload and building the apps.
npm i --save-dev grunt grunt-browserify grunt-contrib-copy grunt-contrib-watch
Obviously if you are developing apps for sometime, you know that scss
and jade
are your usefull friends. Let us add build tools needed for them also. You can remove this step if you think you want to use html and css.
npm i --save grunt-contrib-jade grunt-contrib-sass
needless to say if you are using grunt-contrib-sass
make sure you have the ruby module for scss
installed.
angularjs
and angular-route
In last step we only added dependencied needed for the build, its time to install angular and ngRoute.
npm i --save angular angular-route
Note that i have not added them in dev-dependencies.
Here is a small app structure that i prefer to use to keep my codes manageable
.├── app.js├── components│ ├── nav.jade├── controllers│ ├── index.js│ └── testController.js├── factory│ └── index.js├── index.jade├── route.js├── style│ ├── main.scss└── templates └── application.jade
You can always change that to what suits you. This is inside an app
folder in my npm project.
Edit Gruntfile.js
in your root folder, the one that contains package.json
and put in the following content.
module.exports = function(grunt){ grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), browserify: { 'dist/app.js': ['app/app.js'] }, jade :{ compile: { options: { client: false, pretty : false }, files: [{ cwd: "app", src: "**/*.jade", dest: "dist", expand: "true", ext: ".html" }] } }, watch: { all: { options: {livereload: true}, files: ['app/**'], tasks: ['jade','sass','browserify'] } }, sass:{ dist: { files:{ 'dist/main.css':'app/style/main.scss' } } }, copy: { main: { expand: true, cwd: 'static', src: '**', dest: 'dist/static', }, } });
grunt.loadNpmTasks('grunt-contrib-jade'); grunt.loadNpmTasks('grunt-contrib-sass'); grunt.loadNpmTasks('grunt-contrib-watch'); grunt.loadNpmTasks('grunt-browserify'); grunt.loadNpmTasks('grunt-contrib-copy'); grunt.registerTask('default', ['copy','jade','sass','browserify','watch']);};
That is all that we need for building our app
, which grunt
will build and put in dist
folder.
I am just going to make a simple app that imports nav.
<!--app/index.jade-->doctypehtml.no-js head meta(charset='utf-8') meta(http-equiv='X-UA-Compatible', content='IE=edge') base(href='/') title Application meta(name='description', content='') meta(name='viewport', content='width=device-width, initial-scale=1') link(rel='stylesheet',href='main.css') body(ng-app='application') div(ng-view) script(src='app.js') script(src='//localhost:35729/livereload.js')
The last script of livereload
comes from grunt-watch
and would reload the page when you change anything in your code.
// app/app.jsvar angular = require('angular');var ngRoute = require('angular-route');var app = angular.module('application', [ngRoute]);
require('./route')(app);require('./controllers');
Remember we already have angular
and angular-route
installed.
// app/routes.jsmodule.exports = function(app) { app.config(function($routeProvider, $locationProvider) { $routeProvider .when("/",{ templateUrl: "templates/application.html" }); $locationProvider.html5Mode(true); });};
This is the file where we define all the routes. Note that templates/application.html
is the output of jade from templates/application.jade
.
// app/controllers/index.jsvar app = require('angular').module('application');
app.controller('testController',require('./testController.js'));
This is the file that was imported in app/app.js
, we need to include all controllers here. In this case i have demonstrated with testController
as you can see from the tree structure.
that is more of common reusable stuff like navigation that i keep so my templates directory don’t become cluttered. Example in application.jade
which in this case is the landing page, i can add navigation using
div(ng-include="'/components/nav.html'")
Well first you need to start the build, Simply go to root folder of npm project and run grunt
from terminal. It will build the project and start to look for changes.
You might also see a new directory called dist
. That directory is the final build output for the code. Simply start a web-server
in that directory and go to that url in browser, where you can see the application running.
The moment you make any changes to the code, grunt would automatically run and the browser would reflect the updated changes without the need to reload.