ngBoilerplate: An AngularJS Project Kickstarter

2,836 views
Skip to first unread message

Joshua Miller

unread,
Feb 28, 2013, 9:03:56 PM2/28/13
to angular
Hello everyone!

When I start a new AngularJS project, I always follow the same few steps: recreate a directory structure, copy an old Grunt file, create basic HTML, add the AngularJS overhead, etc. And all of this is before I even start on my project! So I created something that aims to alleviate that, and I post it here so that both (a) it may be of help to others, and (b) I may solicit feedback on the implementation.

ngBoilerplate contains everything a developer needs to kickstart new AngularJS projects: a best-practice directory structure to support scalability and code reuse, an intelligent build system that saves time, and a couple of common web design libraries like Bootstrap. The idea is that I (or whomever) can simply fork the repository and start developing a new app. I created a similar one when I worked with Dojo and found it quite helpful; I'm attempting to  reclaim that success using AngularJS.

For the record, there are competing kickstarters, seeds, sprouts, and boilerplates, but they don't seem to adhere to some of the philosophical principles of architecture I think are required for a good app, so I created my own. The GitHub page discusses these philosophical points in more detail.

Also, before I forget - thanks to everyone here. Most of this I learned from this mailing list and from working on other open-source projects. For example, the directory structure is similar to the awesome `angular-app`.

Some feedback would be awesome! So if you have a few spare minutes, hop on over to http://bit.ly/ngBoilerplate and tell me what you think - I'd love some feedback!

Josh

yahya Kacem

unread,
Feb 28, 2013, 9:42:58 PM2/28/13
to ang...@googlegroups.com
Hi, that seems promising, but isn't Yeoman do that already.

Joshua Miller

unread,
Feb 28, 2013, 10:07:31 PM2/28/13
to angular
Hello!

Not really. Yeoman is a generator and manager - it's a command-line wrapper around tools like Bower and Grunt and can scaffold a new project based on a template. The Yeoman tools are wicked-cool.

Also, there is an AngularJS scaffold that you can use with Yeoman that is based on angular-seed, but I disagree with it on some major points (for example, it packages by layer rather than by feature).

One of the things I'm considering for ngBoilerplate (as noted in the road map) is a scaffold for Yeoman to take advantage of the code generation features. But Bower works out of the box with ngBoilerplate and I'm not entirely convinced of the value of code generators for modules and things. It's one of the areas where I am hoping for community feedback.

Josh


--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to angular+u...@googlegroups.com.
To post to this group, send email to ang...@googlegroups.com.
Visit this group at http://groups.google.com/group/angular?hl=en-US.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Bernd Wessels

unread,
Feb 28, 2013, 10:29:05 PM2/28/13
to ang...@googlegroups.com
Hi Joshua

This looks awesome and is definitely something that will make it easier for angular newbies to start on the right foot. (Yeoman is not yet supported on Windows)

The ultimate goal would be an integrated Google Closure Advanced Compilation in the build process - but I understand that AngularJS needs some massive changes to make that possible.

I will shift my current project into your boilerplate structure and give feedback then.

Cheers
Bernd

Pascal Precht

unread,
Mar 1, 2013, 3:43:25 AM3/1/13
to ang...@googlegroups.com
Hey Joshua!

I think this is actually a pretty good kickstarter. I would prefer it rather then the angular-seed because of the things you already pointed out. Packaging by feature is always best,
since someday, angular will provide lazy loading stuff.

So great work on that, and in my opinion it should be *the* angular seed. 

*Little proposal*: The testacular directory should already contain something like a boilerplate for unit, midway and e2e tests.

Cheers

/pp

Pascal Precht

unread,
Mar 1, 2013, 3:46:25 AM3/1/13
to ang...@googlegroups.com
Ah know what? I'll fork it and send a pull request :)

Joshua Miller

unread,
Mar 2, 2013, 12:39:17 PM3/2/13
to angular
Hey Pascal!

What do you mean by a boilerplate for the tests? It contains a Testacular config for unit tests as well as a few sample unit tests (but they exist alongside what they're testing). I am missing e2e tests as I simply haven't had the time to add them.

If you want to submit a pull request, that would be *awesome*.

Josh


On Fri, Mar 1, 2013 at 12:46 AM, Pascal Precht <pascal...@gmail.com> wrote:
Ah know what? I'll fork it and send a pull request :)

Bernd Wessels

unread,
Mar 3, 2013, 3:50:33 PM3/3/13
to ang...@googlegroups.com
Hi Joshua

What is the best way to stay in sync with your future changes, once I started a new project based on your boilerplate?

Best regards

Bernd

Andy Joslin

unread,
Mar 3, 2013, 4:14:19 PM3/3/13
to ang...@googlegroups.com
I like this Josh!  What do you think about using ngmin? http://github.com/btford/ngmin http://github.com/btford/grunt-ngmin

I'll open a PR unless you're against it (it's new and kind of risky, so...).  But we could at least have a branch for ngmin.

Bernd Wessels

unread,
Mar 3, 2013, 7:26:29 PM3/3/13
to ang...@googlegroups.com
Hi Joshua

Your boilerplate is great. The only think I would change is the old router to the new angular-ui router https://github.com/angular-ui/ui-router/.

I tested it and it fits very well in your boilerplate structure and it offers so much more flexibility than the old router does.

Best regards

Bernd

On Friday, March 1, 2013 3:03:56 PM UTC+13, Joshua Miller wrote:

Joshua Miller

unread,
Mar 3, 2013, 11:56:15 PM3/3/13
to angular
Hey guys - 

@Bernd - Great question about staying in sync! Most it you wouldn't want in sync as it would overwrite your code, but there would be value in manually syncing changes to, for example, the build system. The easiest way to do this is to keep ngBoilerplate as a remote on your git repository and then you can pull new changes into that branch and selectively merge them as necessary into your master or feature branch. I can provide more detail on this if you're not super familiar with git - it's a lot easier than it sounds. In the future, when I have some type of build system (possibly based on Yeoman, possibly something custom that is much simpler) updates would be automated.

As for ui-router, I'm not sure how I feel about incorporating it until it's stable. However, I'd *love* to have a branch with it that we can maintain in the interim for those that want to use it. It's a pretty awesome project. Feel free to submit a pull request and I'll place it on a "ui-router" branch so that we can play with it as the projects mature.

@Andy - For ngmin, I'm not at all against it! It would simplify the code and the array syntax hurts readability. If you have time, submit a PR and I'll at least create a branch for it.

Thanks!

Josh


--

mlegenhausen

unread,
Mar 4, 2013, 4:06:18 AM3/4/13
to ang...@googlegroups.com
That looks great. But I have some questions:

Why are you mixing the jasmine spec files with your productive app directory structure and don't use a separate test directory for it as it is made in all other angular sample applications?

Would it be possible to add the grunt live-reload plugin, so the browser gets automatically updated on file changes?

Dave Merrill

unread,
Mar 4, 2013, 7:03:35 AM3/4/13
to ang...@googlegroups.com
@Josh, I am in fact relatively new to Git, so steps for doing the selective merge would be appreciated. I currently do most of my Git work, but not all, through IntelliJ, and I've wondered how to do that in that context for other exactly similar situations. If you're not an IntelliJ guy, straight-up Git steps would be helpful too, and probably help out more other people.

Dave Merrill

Joshua Miller

unread,
Mar 4, 2013, 2:21:56 PM3/4/13
to angular
Hey Malte -  

I keep specs next to the files they test for a couple of reasons: (1) it's easier to find tests; (2) it makes more sense to me; (3) most importantly, it makes components super reusable. If the tests are in the same directory as the component code, templates, and styles, I can drag and drop that folder into another project to reuse it - everything "just works". If the tests are in a separate directory, not only do I have to remember to copy those too, but also it begins to break down the clean structure I've defined: you can't find everything about a component in one place. It would be fairly trivial to change the Gruntfile to support independent tests, but I do feel this is the best approach.

Also, since you mentioned other AngularJS examples, a big reason why other projects use a separate test directory was because that's what the toolchain supported. Most projects use Grunt, and until version 0.4, Grunt didn't make it very easy to distinguish between two sets of code in the same directory. You could say "*.spec.js" are tests, but you couldn't say "*.js" except "*.spec.js" are sources. Grunt 0.4 allows those negative selectors (with a whole host of other awesome features), but it was released on Feb 18, so others just haven't had the opportunity.

For grunt-livereload, it's an awesome suggestion and pretty handy, but I'm not sure how much I'd have to change to get it to work. Right now, the build process ensures that the file can be viewed without any server, using the "file://" protocol, which I really like. `livereload` requires both a tag in the index.html file as well as the file to be served from a Grunt-initiated server. It'd be cool to have this as an option, though. If you have time, give it a go and submit a pull request. If it's doable to have both options, I'm totally game.

Josh

Joshua Miller

unread,
Mar 4, 2013, 2:32:10 PM3/4/13
to angular
Hey Dave -

I'm one of those Vim guys, so I don't know much about IntelliJ, unfortunately. However, the Git steps are pretty straightforward. I'll add this to docs with a bit more detail, but here's the high-altitude view:

1. Add the repo as a remote:

$ git remote add ngboilerplate git://github.com/joshdmiller/ng-boilerplate

2. And now it's ready. When you want to run updates, selectively merge changes; as an example, say we made changes to the way html2js works:

$ git checkout ngboilerplate/master Gruntfile.js build/grunt-html2js.js
$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   modified:   Gruntfile.js
#   modified:   build/grunt-html2js.js
#
$ grunt
...
$ git commit -m "Merged new html2js build features from ngBoilerplate"

The "git checkout" takes the name of a branch (in this case we gave it the name of the master branch on the ngboilerplate remote repo) and then a list of the files you want to pull. The changes will be automatically staged for commit, so "git add" isn't necessary. You may also want to run "git diff" to see exactly what changed.

But of course we run "grunt" to ensure everything works and our tests still pass before committing the changes. :-)

Using "checkout" won't be the best way in all cases; for example you can't selectively merge changes to a file - it's all or nothing. When I update the docs, I'll provide some alternative options.

Josh

Luis Santos

unread,
Jul 27, 2014, 3:39:39 PM7/27/14
to ang...@googlegroups.com
Hey guys, 

After reading about best practices and ng-boilerplate I have decided to change my project structure to something more oriented to modules so I have now many different ones (I guess I was sold by the idea of having different components you can reuse among different projects). Anyway after i made this separation of code I am getting now the following exception:

  1. Uncaught TypeError: Cannot read property 'apply' of undefined from mixJsApp.main angular.js:2914
    1. (anonymous function)angular.js:2914
    2. forEach


This just happens with the modules that have directives in. Not very sure what I m missing here. This is my main module configuration:

angular.module('mixJsApp', [

        'mixJsApp.domain',
        'mixJsApp.services',
        'mixJsApp.administration',
        'mixJsApp.dashboard',
        'mixJsApp.trading',
        'mixJsApp.reports',
        'mixJsApp.research',

//The following 4 are the ones that have directives and are the ones that give me the exception. (No matter what order I use)

        'mixJsApp.main'
'mixJsApp.currency',
        'mixJsApp.market',
        'mixJsApp.commissions'
        ])
  .config(['$httpProvider', function($httpProvider) {
        $httpProvider.defaults.useXDomain = true;
        delete $httpProvider.defaults.headers.common['X-Requested-With'];
    }]);


Please any help would be appreciated
Luis
Reply all
Reply to author
Forward
0 new messages