{"id":15019413,"url":"https://github.com/danmindru/angular-boilerplate-study","last_synced_at":"2025-09-12T00:32:44.981Z","repository":{"id":57178084,"uuid":"26375410","full_name":"danmindru/angular-boilerplate-study","owner":"danmindru","description":"A study of AngularJS modularity \u0026 organization.","archived":false,"fork":false,"pushed_at":"2015-06-23T11:02:03.000Z","size":1088,"stargazers_count":6,"open_issues_count":3,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-01-01T17:22:42.230Z","etag":null,"topics":["angularjs","angularjs-boilerplate"],"latest_commit_sha":null,"homepage":"http://abs.danmind.ru","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/danmindru.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-11-08T21:30:39.000Z","updated_at":"2022-08-06T14:17:07.000Z","dependencies_parsed_at":"2022-09-11T07:01:11.139Z","dependency_job_id":null,"html_url":"https://github.com/danmindru/angular-boilerplate-study","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danmindru%2Fangular-boilerplate-study","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danmindru%2Fangular-boilerplate-study/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danmindru%2Fangular-boilerplate-study/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danmindru%2Fangular-boilerplate-study/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/danmindru","download_url":"https://codeload.github.com/danmindru/angular-boilerplate-study/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":232674876,"owners_count":18559219,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["angularjs","angularjs-boilerplate"],"created_at":"2024-09-24T19:53:26.937Z","updated_at":"2025-01-06T04:53:21.421Z","avatar_url":"https://github.com/danmindru.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"#AngularJS boilerplate (study)\n[![Build Status](https://travis-ci.org/danmindru/angular-boilerplate-study.svg?branch=master)](https://travis-ci.org/danmindru/angular-boilerplate-study) [![devDependency Status](https://david-dm.org/danmindru/angular-boilerplate-study/dev-status.svg)](https://david-dm.org/danmindru/angular-boilerplate-study#info=devDependencies)\n\nThis study looks at AngularJS boilerplates to find the best approaches so you don't have to. Although plenty of choices are available, they will do justice for only some types of applications. There is no one-size-fits all, universal boilerplate.\nPlan your app well, prototype it and then refactor. If you still think it's a good idea to use a boilerplate, choose one and adapt it to your needs.\n\n[See this app in action](http://abs.danmind.ru).\n\n[See a live app built with this boilerplate](http://fadeit.dk).\n\n\n##Getting started\n\nInstall `npm` and `bower` dependencies and run `grunt`, that's it. You are good to go.\n\n```\n$ sudo npm install\n$ bower install\n$ grunt\n```\n\nAfter running grunt, the source files will be built into `./build`.\n\nWhen the app is ready for production, compile the app into `./application` by running:\n\n```\n$ grunt compile\n```\n\n###Requirements\n`Grunt`, `grunt-cli` and `Bower` are required to build the application.\nRead more about these packages [on the Grunt](http://gruntjs.com/installing-grunt) or [Bower](http://bower.io/) documentation pages.\n\n\n##Table of contents\n\n  1. [Philosophy](#philosophy)\n  1. [Application structure](#application-structure)\n  1. [Build and compile](#build-and-compile)\n    * [Build](#build)\n    * [Compile](#compile)\n  1. [Core components](#core-components)\n  1. [Third party components](#third-party-components)\n  1. [Conventions and best practices](#conventions-and-best-practices)\n  1. [Testing](#testing)\n    * [Unit testing](#unit)\n    * [End to end testing](#end-to-end)\n\n##Philosophy\n\nThe modular nature of AngularJS (mainly) facilitated the development of numerous boilerplates. Based on the *insanely* comprehensive analysis done by Dan Cancro ([link](http://www.dancancro.com/comparison-of-angularjs-application-starters/)), it's noticeable that boilerplates exist for certain purposes and are not in fact the result of different approaches to achieve the same exact thing. There is no question that they do have the common purpose of quickly starting off development. At the same time, they are forcing some patterns/concepts that their creators think help in *some way*. This is where it's easy to see why they are different. There are many nuances to *some way*, it can be:\n  * **flexibility**\n  * **performance**\n  * **learnability/documentation**\n  * **efficiency (as in increased dev. speed)**\n  * **testability**\n  * **architecture (structure/overview/understanding)**\n  * **maintainability**, etc\n\nSome developers will value one of them more than the others. This doesn't mean that if testability is considered to be the most important, the others will be neglected. In fact, you probably won't be able to address one issue without affecting the others. It's easier to get this if you look at what this man had to say back when 'personal' and 'computer' where two unrelated terms:\n\n\u003e \"The benefits expected of modular programming are: managerial-development time should be shortened because separate groups would work on each module with little need for communication: product flexibility-it should be possible to make drastic changes to\none module without a need to change others; comprehensibility-it should be possible to study the system one module at a time. The whole system can therefore be better designed because it is better understood.\"\n\n\u003e **Parnas, D. L. On the Criteria To Be Used in Decomposing Systems into Modules, 1972**\n\n\nModularity's umbrella can cover most of the decisions we consider when creating a boilerplate. Therefore, that's the first thing this study focuses on: getting modularity right.\n\nPerformance and comprehensibility are chosen as being the focus areas of this boilerplate. The two don't usually play well, that's why this makes for a somewhat noble goal. On one hand, performance decisions can be measured and justified. That's going to make some implementations easier to digest. On the other hand, comprehensibility is more personal and hard to measure. That's why it will require more research \u0026 testing.\n(more on this in the [Conventions and best practices chapter](#conventions-and-best-practices))\n\nFinally, the result of this study embraces the idea of `certain boilerplates work best for certain applications`. It's based on a real project with clear demands, a specific development setup, a given team \u0026 a specific set of tools (technologies).\n\n\n##Application structure\n\n```sh\nroot/\n+—— src/\n|   +—— app/\n|   |   +—— _app-main/ # Root module -\u003e application bootstrap\n|   |   |   +—— _app-main.config.js\n|   |   |   +—— _app-main.controller.js\n|   |   |   +—— _app-main.init.js\n|   |   |   +—— _app-main.spec.js\n|   |   +—— module/ # Any custom module\n|   |   |   +—— module.config.js # Registering a module\n|   |   |   +—— module.controller.js\n|   |   |   +—— module.e2e.js # Module E2E test\n|   |   |   +—— module-page.html # Module views\n|   |   |   +—— module.spec.js # Module Unit test\n|   |   +—— feature/ # Any custom feature (multiple modules)\n|   |   |   +—— module-one/\n|   |   |   |   +—— module-one.config.js\n|   |   |   |   +—— module-one.controller.js\n|   |   |   |   +—— module-one-page.html\n|   |   |   |   +—— module-one.spec.js\n|   |   |   +—— module-two/\n|   |   |   |   +—— module-two.config.js\n|   |   |   |   +—— module-two.controller.js\n|   |   |   |   +—— module-two-page.html\n|   |   |   |   +—— module-two.spec.js\n|   |   |   +—— feature.config.js\n|   |   |   +—— feature.e2e.js\n|   |   +—— shared/ # Shared modules\n|   |   |   +—— directive/ # Any shared directive\n|   |   |   |   +—— directive.directive.js\n|   |   |   |   +—— directive.html\n|   |   |   +—— layout/ # Shared layout directives\n|   |   |   |   +—— footer.directive.js\n|   |   |   |   +—— footer.html\n|   |   |   |   +—— layout.config.js\n|   |   |   |   +—— layout.controller.js\n|   |   |   |   +—— shell.directive.js\n|   |   |   |   +—— shell.html\n|   |   |   +—— model/ # Any shared model\n|   |   |   |   +—— model.config.js\n|   |   |   |   +—— model.service.js\n|   +—— assets/ # All application assets\n|   |   +—— css/\n|   |   +—— fonts/\n|   |   +—— images/\n|   |   +—— less/\n|   +—— common/ # Common modules\n|   |  +—— loggly/\n|   |  |   +—— loggly.config.js\n|   |  |   +—— loggly-exception-decorator.service.js\n|   |  |   +—— loggly-exception-logging.service.js\n|   |  |   +—— loggly-trace.service.js\n|   +—— test/ # Protractor helper methods (e2e tests)\n|   |  |   +—— helpers.protractor.js\n|   +—— index.html # Application index file\n```\n\nBrowse the `./src` directory for examples.\n\nGo to [src/app/shared](https://github.com/danmindru/angular-boilerplate-study/tree/master/src/app/shared) for more info on shared modules.\n\nGo to [src/common](https://github.com/danmindru/angular-boilerplate-study/tree/master/src/common) for more info on common modules.\n\n\n##Build and compile\n\nA 2-stage Grunt 'strategy' is implemented.\n\nFor development, files will go to `./build`.\nFor production, files will be concatenated, uglyfied / minified and moved to `./application`. (1 css, 1 js)\n\n\n###Build\nThe build task will do all the work for development and create files in -\u003e `./build`\n\n```\n$ grunt build\n```\nYou can use the following command to start the build http server (port 8008 default):\n\n```\n$ grunt dev\n```\n\n\n###Compile\nThe compile task will do all the work for production and create files in -\u003e `./application`\n\n```\n$ grunt compile\n```\nYou can use the following command to start the build http server (port 8009 default):\n\n```\n$ grunt prod\n```\n\n###Watch\nThe `watch` task builds JavaScript, HTML and all assets (including tests and the gruntfiles themselves) when any of them are changed.\n\n\n##Core components\n\nThe only 'core' AngularJS modules are:\n* `_app-main`: contains logic for manually bootstrapping the application, sets up a module for `$templateCache`, allows defining 3rd party dependencies and exposes a method to register modules: `pushAfterBootstrap`.\n* `layout`: (inside `app/shared`) contains the `ng-view` directive to display content based on the current route (`ui-router` specific directive). `layout` contains other directives for footer \u0026 navigation, but they can be removed. The `shell` directive is the one responsible for `ng-view`.\n\n\nTo start clean, you can remove the directories of sample modules or features: `/app/about`, `/app/home`, `/app/profile-feature` and `app/shared/profile-model` can be safely removed.\n\n*Note: `app/shared/profile-model` is a dependency of `/app/home` and `/app/profile-feature`. Removing the modules also requires the navigation directive in `/app/shared/layout/` to be updated.*\n```sh\n# For the lazy developer, just run the following to\n# remove the sample modules:\n\n$ grunt clean:clean_samples\n```\n\n\n##Third party components\n\nWith the exception of `ui-router`, third party components that are used to build the sample application are just a recommendation. They can be replaced with any other similar components or completely removed.\n\n\n\u003cdl\u003e\n  \u003cdt\u003ebootstrap\u003c/dt\u003e\n  \u003cdd\u003eTwitter Bootstrap is used for it's CSS properties and icon-fonts (JS not included). If there are any plans to use Bootstrap's JavaScript, jQuery needs to be added (it's already downloaded in \u003ccode\u003e./vendor/\u003c/code\u003e when Bootstrap is resolved).\u003cdd\u003e\n\n  \u003cdt\u003eLESS\u003c/dt\u003e\n  \u003cdd\u003eCSS can be pre-processed using LESS. To make things even sweeter, \u003cb\u003egrunt-autoprefixer\u003c/b\u003e will add all CSS prefixes for you automatically. No more \u003cb\u003e-webkit-\u003c/b\u003e, \u003cb\u003e-moz-\u003c/b\u003e, \u003cb\u003e-ms-\u003c/b\u003e, etc in your source files ever! (Support for SASS is NOT implemented)\u003cdd\u003e\n\n\n  \u003cdt\u003estacktrace.js\u003c/dt\u003e\n  \u003cdd\u003eStacktrace is a components that allows debugging JavaScript by giving a full stack trace of function calls. It's a dependency of the \u003ccode\u003eloggly\u003c/code\u003e module in \u003ccode\u003e./src/common/loggly/\u003c/code\u003e.\u003cdd\u003e\n\n\n  \u003cdt\u003eloggly-jslogger\u003c/dt\u003e\n  \u003cdd\u003eThis component is a client-side (browser) logger and it's also a dependency of the \u003ccode\u003eloggly\u003c/code\u003e module in \u003ccode\u003e./src/common/loggly/\u003c/code\u003e. It allows setting up loggly and storing exceptions in the cloud.\u003cbr/\u003e\u003cbr/\u003e\n  Loggly is very easy to configure for your account; it only requires one change in \u003ccode\u003e./src/common/loggly/loggly.config.js\u003c/code\u003e.\u003cdd\u003e\n\n  \u003cdt\u003eui-router\u003c/dt\u003e\n  \u003cdd\u003eA routing framework for AngularJS. See more on the [ui-router repository](https://github.com/angular-ui/ui-router).\u003cdd\u003e\n\n\n  \u003cdt\u003eangular-mocks\u003c/dt\u003e\n  \u003cdd\u003eA module that provides support to inject and mock Angular services into unit tests. Read the docs on the \u003ca href=\"https://docs.angularjs.org/api/ngMock\" target=\"_blank\"\u003eAngular site\u003c/a\u003e.\u003cdd\u003e\n\n\n  \u003cdt\u003eKarma\u003c/dt\u003e\n  \u003cdd\u003eKarma is the chosen test runner for Jasmine unit tests. It can be configured in \u003ccode\u003e./config/karma.conf.js\u003c/code\u003e.\u003cdd\u003e\n\n\n  \u003cdt\u003eProtractor\u003c/dt\u003e\n  \u003cdd\u003eProtractor is an end-to-end test framework for AngularJS applications. Protractor is built on top of WebDriverJS (it requires a running Selenium Server, read more about here: \u003ca href=\"#end-to-end\"\u003eEnd to end testing\u003c/a\u003e).\u003cdd\u003e\n\n\n  \u003cdt\u003eTravis CI\u003c/dt\u003e\n  \u003cdd\u003eTravis CI is a hosted continuous integration service. It is integrated with GitHub and automatically runs unit and end to end tests for each build. You need to sign up in order to use this service (free for open source projects).\n\n  \u003ca href=\"https://travis-ci.org/danmindru/angular-boilerplate-study/builds\" target=\"_blank\"\u003eSee the builds for this repository on Travis CI\u003c/a\u003e\u003cdd\u003e\n\n\n  \u003cdt\u003eSauceLabs\u003c/dt\u003e\n  \u003cdd\u003eWhenever Travis CI runs a new build, SauceLabs provides a standalone Selenium server and runs end to end tests automatically (here's an example: \u003ca href=\"https://saucelabs.com/tests/a40d7a31221843049b69a37a575e3b60\" target=\"_blank\"\u003eBuild 64\u003c/a\u003e). You need to sign up to use this service (\u003ca href=\"https://saucelabs.com/opensauce\" target=\"_blank\"\u003efree for open source projects\u003c/a\u003e).\n\n  To set up Sauce Labs with Travis CI you have to provide a SauceKey and SauceUsername securely in \u003ccode\u003e./.travis.yml\u003c/code\u003e (you can remove all 3 secure env variables). See how to do it in \u003ca href=\"https://docs.saucelabs.com/ci-integrations/travis-ci/\" target=\"_blank\"\u003eSauceLabs' docs\u003c/a\u003e.\u003cdd\u003e\n\u003c/dl\u003e\n\n###Grunt 'contrib' tasks\nGrunt tasks are used in order to automate the build and compilation of the app code.\nOpen `./package.json` to see the installed Grunt tasks. An external configuration file is used to define file locations in `./config/grunt.conf.js`. Both the config file and `./grunfile.js` are well commented. Reading it would be a good way to fully understand how the Grunt tasks work, but you don't have to.\n\n`jit-grunt` and `grunt-newer` are used to speed up tasks.\n\n\n##Conventions and best practices\n\n###Workflow conventions\nThese conventions should be followed during normal development.\n\n--------------------------\n\n####Working with Grunt\nAs a rule, Grunt tasks (`./grunfile.js`) shouldn't require any alteration. Changes should be made in `./config/grunt.conf.js`. Before adding/changing a task, it's always a good idea to go through all tasks and check if it's not already there.\n\n--------------------------\n\n####Adding a third party dependency\nGrunt 'glues together' the various application components and moves Bower dependencies where they belong (i. e. `../bootstrap/dist/css/bootstrap.min.css` -\u003e `../assets/css`). Due to the way Bower dependencies are organized (well they aren't, really), this process cannot be fully automated. To add a third party dependency, you need to:\n\n**Step 1**: Install it\n```\n$ bower install \u003ccomponent-name\u003e\n```\n**Step 2**: Update the build object in `./config/grunt.conf.js`\n```javascript\n...\nbuild: {\n  vendor_js: {\n    ...\n    './vendor/component-name/dist/js/component.js' //not minified\n    ...\n  }\n}\n...\n```\n**Step 3**: Update the compile object in `./config/grunt.conf.js`\n```javascript\n...\ncompile: {\n  vendor_min_js: {\n    ...\n    './vendor/component-name/dist/js/component.min.js' //minified\n    ...\n  }\n}\n...\n```\n\n*\u003cb\u003eStep 4 (optional)\u003c/b\u003e : If it's an Angular core component (such as `ui-route`), it should be added to the `appMainVendorDependencies` Array in the root module's init file (`./src/app/_app-main/_app-main.init.js`).*\n\n\nProviding different source files for build and compile phases is done for a couple reasons:\n\n1. During build (aka. development time) meaningful error messages/exceptions should be provided for debugging.\n1. During build, it's useful to have the code 'beautified' (line numbers) and not 'mangled' (full variable names)\n1. There is no reason to minify a script if it's already minified by a vendor\n1. Attempting to minify a vendor script can break it (it can have it's own minifying settings)\n\nFor a more in-depth look, `./config/grunt.conf.js` contains useful comments.\n\n--------------------------\n\n####Naming conventions\n\n\n#####Files and directories\nLower case, separated by a dash\n* Directory: `src/directory-name/`\n* Filename: `file-name.js`\n\n--------------------------\n\n#####AngularJS directories\n* Module dirs: `\u003cmodule-name\u003e/`\n* Feature dirs: `\u003cfeature-name\u003e-feature/` (contains multiple modules)\n* Model dirs: `\u003cmodule-name\u003e-model/` (contains services)\n\n--------------------------\n\n#####AngularJS component filenames\n* Init/globals: `\u003cmodule-name\u003e.init.js`\n* Config blocks: `\u003cmodule-name\u003e.config.js`\n* Run blocks: `\u003cmodule-name\u003e.run.js`\n* Services: `\u003cmodule-name\u003e.service.js` (including factories, providers, values)\n* Controllers: `\u003cmodule-name\u003e.controller.js`\n* Directives: `\u003cmodule-name\u003e.directive.js`\n* Filters: `\u003cmodule-name\u003e.filter.js`\n* Views: `\u003cview-name\u003e.html`\n\n--------------------------\n\n#####Other files\n* E2E tests: `\u003cmodule-name\u003e.e2e.js`, `\u003cfeature-name\u003e.e2e.js` (depending on the case)\n* E2E helpers: `\u003cname\u003e.protractor.js`\n* Unit tests: `\u003cmodule-name\u003e.spec.js`\n\n--------------------------\n\n#####Angular modules\n* Module names: `\u003cnamespace\u003e.\u003cmoduleName\u003e`\n* Feature names (collection of modules): `\u003cnamespace\u003e.\u003cfeatureName\u003eFeature`\n* Nested modules (inside a feature): `\u003cnamespace\u003e.\u003cfeatureName\u003eFeature.\u003cmoduleName\u003e`\n\n(i.e. `abs.about`, `abs.profileFeature`, `abs.profileFeature.providerPage`)\n\n\n* Core modules: `\u003cnamespace\u003e.core\u003cModuleName\u003e`\n* Core features: `\u003cnamespace\u003e.core\u003cFeatureName\u003eFeature`\n* Core nested module: `\u003cnamespace\u003e.core\u003cFeatureName\u003eFeature.core\u003cModuleName\u003e`\n\n(i.e. `abs.coreLayout`)\n\n\n* Common modules: `\u003cnamespace\u003e.common\u003cModuleName\u003e`\n* Common features: `\u003cnamespace\u003e.common\u003cFeatureName\u003eFeature`\n* Common nested: `\u003cnamespace\u003e.common\u003cFeatureName\u003eFeature.common\u003cModuleName\u003e`\n\n(i.e. `abs.commonLoggly`)\n\n\n* Model names: `\u003cnamespace\u003e.\u003cmodelName\u003eModel`\n* Nested models: `\u003cnamespace\u003e.\u003cparentModel\u003eModel.\u003cmodelName\u003eModel`\n\n(i.e. `abs.profileModel`, `abs.profileModel.customerModel`)\n\n--------------------------\n\n#####Angular module components\n* Controllers: `\u003cControllerName\u003eController`\n* Models: `\u003cModelName\u003e\u003cModelType\u003e` (ModelType could be service, factory, value)\n* Directives: `\u003cdirectiveName\u003e`\n* Filters: `\u003cfilterName\u003e`\n\n--------------------------\n\n####Creating a module\nTo create a module, make a directory in a corresponding location:\n* `./src/app/` for any basic module\n* `./src/app/shared/` for any shared module (i.e. directive, shared layout)\n* `./src/common/` for any [common module](https://github.com/danmindru/angular-boilerplate-study/tree/master/src/common)\n\nAfter making the directory, create a config file (`\u003cmodule-name\u003e.config.js`). In this file the module needs to be registered as a dependency of the application root.\n```javascript\nabsConfig.pushAfterBootstrap('\u003cnamespace\u003e.\u003cmodule-name\u003e');\n```\nThat's it, use it as any other Angular module.\n\nHere's a more practical example:\n```javascript\nabsConfig.pushAfterBootstrap('abs.home');\n\nangular.module('abs.home').config(homeConfig);\nhomeConfig.$inject = ['$log'];\n\nfunction homeConfig($log){\n  $log.warn('I am being practical');\n}\n```\n\n--------------------------\n\n####Component dependency injection\n\nDependencies are injected into components by creating a $inject property on the component function:\n```javascript\nangular.module('user').controller('UserController', userController);\n\nuserController.$inject = ['$scope', '$stateParams', 'ProviderModelService'];\nfunction userController($scope, $stateParams, ProviderModelService){\n  //controller logic\n}\n```\n\nNote on annotation:\n\nFirst of all automatic annotation is not implemented, although it can be achieved with `ng-annotate`. This is so because every now and then `ng-annotate` backfires. After many hours of debugging, you'll promise yourself to never use it and avoid such situations. Therefore, the 'old-school' annotation is used, but with a twist: it's not done inline with the component (in this case controller) definition. This makes it easy to have an overview of dependencies and easily manage them while being minification-proof.\n\n--------------------------\n\n####File locations during build/compile\n\u003cdl\u003e\n  \u003cdt\u003eShared views\u003c/dt\u003e\n  \u003cdd\u003e\n  All views in \u003ccode\u003e./src/app/shared/\u003c/code\u003e will be located in \u003ccode\u003e./src/shared-views/\u003c/code\u003e after build or compile.\n\n  \u003cbr/\u003e\u003cbr/\u003e\n  \u003cem\u003eNote: compiling will combine all shared views in a module and use $templateCache to define their location. The directory above won't exist in the compile phase, but the views will still be accessible in the same location.\u003c/em\u003e\n  \u003c/dd\u003e\n\n  \u003cdt\u003e'Non-shared' views\u003c/dt\u003e\n  \u003cdd\u003eAll other views will be available in \u003ccode\u003e./build/views/\u003c/code\u003e(build phase) and \u003ccode\u003e./application/views/\u003c/code\u003e(compile phase).\u003c/dd\u003e\n\n  \u003cdt\u003eStatic assets\u003c/dt\u003e\n  \u003cdd\u003eWith the exception of stylesheet files which are concatenated and compiled, all assets will maintain their directory structure.\u003c/dd\u003e\n\u003c/dl\u003e\n\n--------------------------\n\n####Routes\n\nRoutes are defined in module configuration blocks. In the case of features, routes are defined in the feature configuration block. The idea behind keeping the route logic in each module or feature is to encourage a higher modularity of components. Moreover, keeping module logic\n\nExamples are available in the configuration block of the [home module](https://github.com/danmindru/angular-boilerplate-study/blob/master/src/app/home/home.config.js) and [profile feature](https://github.com/danmindru/angular-boilerplate-study/blob/master/src/app/profile-feature/profile-feature.config.js).\n\n--------------------------\n\n####Performance \u0026 Misc\nOther style considerations:\n* Only perform DOM manipulations with directives\n* Use ng-bind, avoid interpolations\n* Use the bind-once syntax to reduce watchers where possible\n* Always use the 'controller as' syntax\n* Each file holds one component (be it controller, directive, etc)\n* Used data-* for attributes\n* Use ui-sref instead of href for internal anchors\n* Try to use 'ng-repeat as' while filtering to display a 'no results' message\n* Don't use inline filters and ng-repeats if there's another way to achieve the same thing\n\n\n##Testing\n\nTo run all tests use:\n\n```\n$ grunt test\n```\n*Note: you should have a selenium server running, see [end to end testing](#end-to-end)*\n\n*Note: this won't build or compile, but just run all unit and end to end tests for the build binaries, which should be present in `./build`.*\n\n\n###Unit\nTo run unit tests it will come in handy to install karma-cli (if you don't have it yet).\nUnit tests will run on PhantomJS, but if you have binaries for other browsers you are encouraged to add them in `karma.conf.js`\n\n```\n$ npm install -g karma-cli\n$ grunt test:unit\n```\n\nYou can use the continuous task while writing tests to auto refresh your changes\n\n```\n$ grunt karma:continuous\n```\n\nUnit tests will run in the grunt default task (which builds first)\n\n```\n$ grunt\n```\n\n###End to end\nProtractor is used for running end to end tests. Before running the tests be sure the webdriver-manager is updated.\nProtractor's base url is `http://localhost:8008/#!`, but can be changed in `protractor.conf.js` - just make sure the application port matches the base url.\nIn order to run Protractor tests, a selenium server needs to be running (default at `http://localhost:4444/wd/hub`):\n\n```\n$ node_modules/protractor/bin/webdriver-manager start\n$ grunt test:e2e\n```\n\nIf you are running tests for the first time don't forget to update the webdriver\n\n```\n$ node_modules/protractor/bin/webdriver-manager update\n```\n\n##What's coming next\n* Add `grunt-perfbudget` for better performance monitoring, perhaps together with `grunt-pagespeed`\n* Add `uncss` in the workflow (with `phantomcss`)\n* Switch to Angular dependency 'strict mode'\n* Extend documentation: provider visual resources for build \u0026 sample application structure; add a list of 'features' in the boilerplate about page\n* Create unit tests for the home, customer-index \u0026 provider-index modules\n* Extend E2E tests to at least cover all routes\n\nOther future additions:\n- *Include `phantomas` in the workflow - make perf reporting trends ?*\n- *Reduce repetition in CSS - use `parker`, `colorguard` ?*\n- *Use debug: false in production ?*\n- *Try `useApplyAsync` for httpProvider ?*\n- *Implement a form and animation example ?*\n- *Change remaining inline filters to controller filters ?*\n- *Work on Windows support (shell commands) ?*\n- *Move dev/prod demo to github pages ?*\n\n\n##Mentions\n\nSpecial thanks to the people at [fadeit.dk](http://fadeit.dk) for their patience and to [Niels Henrik Juul Hansen](https://github.com/nielshenrikjuulhansen) for guiding me.\n\n\n##License\n\nCopyright (c) Dan Mindru \u003cmindrudan@gmail.com\u003e\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanmindru%2Fangular-boilerplate-study","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdanmindru%2Fangular-boilerplate-study","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanmindru%2Fangular-boilerplate-study/lists"}