├── .bowerrc ├── .editorconfig ├── .gitattributes ├── .gitignore ├── .jshintrc ├── .travis.yml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── bower.json ├── build ├── build.config.js ├── karma.config.js └── protractor.config.js ├── client ├── apple-touch-icon-precomposed.png ├── assets │ └── images │ │ ├── angular-logo.png │ │ ├── bower-logo.png │ │ └── gulp-logo.png ├── favicon.ico ├── humans.txt ├── index.html ├── src │ ├── app │ │ ├── app.js │ │ ├── getting-started │ │ │ ├── getting-started.js │ │ │ └── getting-started.tpl.html │ │ └── home │ │ │ ├── home.js │ │ │ └── home.tpl.html │ ├── common │ │ ├── directives │ │ │ └── version.js │ │ ├── filters │ │ │ └── uppercase.js │ │ ├── footer.js │ │ ├── footer.tpl.html │ │ ├── header.js │ │ ├── header.tpl.html │ │ ├── interceptors │ │ │ └── httpInterceptor.js │ │ └── services │ │ │ └── dataService.js │ └── scss │ │ ├── _base.scss │ │ ├── _helpers.scss │ │ ├── _mixins.scss │ │ ├── _settings.scss │ │ ├── _states.scss │ │ ├── layouts │ │ └── _page.scss │ │ ├── main.scss │ │ └── modules │ │ ├── _buttons.scss │ │ ├── _horizontal-list.scss │ │ └── _island.scss └── test │ ├── e2e │ └── 01.home.scenario.js │ ├── screenshots │ └── README.md │ ├── unit-results │ └── README.md │ ├── unit │ ├── app │ │ ├── app.spec.js │ │ └── home │ │ │ └── home.spec.js │ └── common │ │ ├── directives │ │ └── version.spec.js │ │ └── filters │ │ └── uppercase.spec.js │ └── utils.js ├── gulpfile.js ├── package.json └── server └── README.md /.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "client/src/vendor", 3 | "json": "bower.json" 4 | } 5 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | 8 | [*] 9 | 10 | # Change these settings to your own preference 11 | indent_style = space 12 | indent_size = 2 13 | 14 | # We recommend you to keep these unchanged 15 | end_of_line = lf 16 | charset = utf-8 17 | trim_trailing_whitespace = true 18 | insert_final_newline = true 19 | 20 | [*.md] 21 | trim_trailing_whitespace = false 22 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # general 2 | .idea 3 | .DS_Store 4 | *~ 5 | .sass-cache 6 | 7 | # package control 8 | node_modules 9 | client/src/vendor 10 | 11 | # logs 12 | npm-debug.log 13 | 14 | # build 15 | build/tmp 16 | build/dist 17 | 18 | #test 19 | client/test/screenshots/* 20 | !client/test/screenshots/README.md 21 | client/test/unit-results/* 22 | !client/test/unit-results/README.md 23 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "globals": { 3 | "angular": false 4 | }, 5 | "node": true, 6 | "browser": true, 7 | "bitwise": true, 8 | "camelcase": true, 9 | "curly": true, 10 | "immed": true, 11 | "latedef": true, 12 | "newcap": true, 13 | "trailing": true, 14 | "quotmark": "single", 15 | "strict": true, 16 | "multistr": true, 17 | "debug": false, 18 | "forin": true, 19 | "undef": true, 20 | "plusplus": true, 21 | "eqeqeq": true, 22 | "validthis": false, 23 | "unused": true 24 | } 25 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '0.10' 4 | before_install: 5 | - 'gem update --system' 6 | - 'gem install sass' 7 | - 'npm install -g gulp' 8 | - 'npm install -g bower' 9 | - 'bower install' 10 | branches: 11 | only: 12 | - master 13 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 1.1.0 (2015-08-05) 2 | 3 | ### Bug fixes 4 | 5 | * updating dependencies 6 | 7 | # 1.0.4 (2015-19-01) 8 | 9 | ### Bug fixes 10 | 11 | * fixing issue with protractor 12 | 13 | # 1.0.3 (2015-15-01) 14 | 15 | ### Bug fixes 16 | 17 | * fixing issue with karma config about loading wrong files 18 | 19 | # 1.0.2 (2014-11-6) 20 | 21 | ### Bug fixes 22 | 23 | * updating dependencies 24 | * optimizing code base 25 | 26 | # 1.0.1 (2014-10-30) 27 | 28 | ### Bug fixes 29 | 30 | * docs improvement 31 | 32 | # 1.0.0 (2014-10-29) 33 | 34 | ### Features 35 | 36 | * transition to gulpjs 37 | * removed backend stuff 38 | * e2e testing support with protractor 39 | * using purecss + SMACSS 40 | * following AngularJS styleguide by todd motto 41 | 42 | # 0.0.2 (2013-12-11) 43 | 44 | ### Features 45 | 46 | * grunt unit task 47 | 48 | ### Bug fixes 49 | 50 | * docs improvement 51 | 52 | 53 | # 0.0.1 (2013-12-07) 54 | 55 | ### Features 56 | 57 | * javascript files continuous linting. 58 | * sass continuous compiling. 59 | * unit test ready and configured. 60 | * html templates converted into strings and attached to javascript files (to avoid one http call for every template). 61 | * proxy every request to `/api` (configurable of course) to your backend listening on another port. 62 | * livereload 63 | * static resources minification and optimization for production 64 | * html5mode enabled by default (and fully handled by the build connect middleware) 65 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Reporting issues 2 | 3 | 1. Feel free to report any issue or proposal. 4 | 5 | ## Pull requests 6 | 7 | 1. Fork it 8 | 2. Create your feature branch (`git checkout -b my-new-feature`) 9 | 3. Test your changes to the best of your ability. 10 | 4. Update the documentation to reflect your changes if they add or changes current functionality. 11 | 5. Commit your changes (`git commit -am 'Added some feature'`) 12 | 6. Push to the branch (`git push origin my-new-feature`) 13 | 7. Create new Pull Request 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Alessandro Arnodo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [angular-kickstart](http://vesparny.github.io/angular-kickstart/) 2 | 3 | 4 | Sponsor 5 | 6 | 7 | [![Build Status](https://secure.travis-ci.org/vesparny/angular-kickstart.svg)](http://travis-ci.org/vesparny/angular-kickstart) 8 | 9 | **Brought to you by [Alessandro Arnodo](http://alessandro.arnodo.net) [[@vesparny](https://twitter.com/vesparny)]** 10 | 11 | [![Dev dependency status](https://david-dm.org/vesparny/angular-kickstart/dev-status.png)](https://david-dm.org/vesparny/angular-kickstart#info=devDependencies "Dependency status") 12 | 13 | **Speed up your [AngularJS](http://angularjs.org) development with a complete and scalable gulpjs based build system that scaffolds the project for you. Just focus on your app, angular-kickstart will take care of the rest.** 14 | *** 15 | 16 | #### See a [working demo](http://vesparny.github.io/angular-kickstart/). 17 | 18 | ### What and Why 19 | 20 | angular-kickstart is an opinionated kickstart for single page application development with AngularJS. It makes your development and testing easy, keeps the structure of the project consistent and allows you to create a fully optimized production release with ease. After having developed a lot of AngularJS projects I decided to collect here what I've learnt. 21 | 22 | ### Getting started 23 | 24 | Install **node.js**. Then **gulp** and **bower** if you haven't yet. 25 | 26 | $ npm -g install gulp bower 27 | 28 | After that, install angular-kickstart downloading the [latest release](https://github.com/vesparny/angular-kickstart/releases) (or clone the master branch if you want to run the development version). Unzip the project and cd into it, then install bower and npm dependencies, and run the application in development mode. 29 | 30 | $ npm install 31 | $ bower install 32 | $ gulp serve 33 | 34 | You are now ready to go, your applcation is available at **http://127.0.0.1:3000**. 35 | 36 | **Every file you add, edit or delete into the `/client` folder will be handled by the build system**. 37 | 38 | When you are ready to build a production release there is a task for that: 39 | 40 | $ gulp serve:dist 41 | 42 | This task will lint your code, optimize css js and images files, run unit tests. After the task has successfully finished, you can find an optimized version of your project inside the `/build/dist` folder. 43 | 44 | ### Features 45 | 46 | * 5 simple task: `gulp serve`,`gulp serve:dist`, `gulp serve:tdd`, `gulp test:unit`, `gulp test:e2e` 47 | * JavaScript file continuous linting with `jshint`. 48 | * SASS continuous compiling. 49 | * `Unit` and `e2e` testing support. (for `e2e` testing you need to have a java runtine installed, take a look at [selenium JavaScript api ](http://selenium.googlecode.com/git/docs/api/javascript/index.html) and [protractor](https://github.com/angular/protractor) for more informations. 50 | * HTML templates converted into strings and attached to a single javascript file (to avoid one http call for each template). 51 | * Livereload provided by [browsersync](http://www.browsersync.io/). 52 | * angular module dependencies automatically injected using [ng-annotate](https://github.com/olov/ng-annotate). 53 | * Static resources minification and optimization for production. 54 | * sourcemaps generated and embedded in JavaScript and css files during the production optimization. 55 | 56 | ### Directory Structure 57 | 58 | * `build/` - Build files and configuration, the most important files to note are `build.config.js`, `protractor.config.js` and `karma.config.js`. These files are the heart of the build system. Take a look. 59 | * `client/` the source code and tests of your application, take a look at the modules in this folder, you should structure your application following those conventions, but you can choose another convention as well. 60 | * `.bowerrc` - the bower configuration file. This tells Bower to install components in the `client/src/vendor` directory. 61 | * `.jshintrc` - JSHint configuration. 62 | * `gulpfile` - see [The Build System](#thebuildsystem) below. 63 | * `bower.json` - Contains the list of bower dependencies. 64 | * `package.json` - node.js dependencies. 65 | 66 | ### The Build System 67 | 68 | There are some `tasks` available in `gulpfile.js`. You can dig into the file to familiarize yourself with gulpjs. 69 | 70 | A description of every available task: 71 | 72 | * **gulp serve** - When this task runs, the build will take care of watching files. Every time you change a file in the `client/` folder, the build recompiles every file, and your browser will reload automagically showing you the changes. 73 | You just need to add new JavaScript and css files in the `client/index.html` file. 74 | * **gulp serve:dist** - This task will run jshint and unit tests under the `client/test/unit` folder (thanks to `karma runner`), and create a fully-optimized version of your application under the `build/dist/` folder. The optimization consists of concatenate, minify and compress js and css files, optimize images, and put every template into a js file loaded by the application. 75 | A code coverage report will be available inside the `client/test/unit-results`. 76 | **Note to change browser-sync's server port, change the 'port' and 'uiIPort' settings in build/build.config.js.** 77 | * **gulp serve:tdd** - Just like `gulp serve` but in continuous unit testing environment. 78 | * **gulp test:unit** - For running unit tests one time then exit. 79 | * **gulp test:e2e** - Run end-to-end tests inside the `client/test/e2e` folder with `protractor`. If a test fails, you should find a screenshot of the page inside the `client/test/screenshots` folder. 80 | **Note that you need to have the application running in order to run e2e tests. You can launch this task from another terminal instance.** 81 | 82 | ### Contributing 83 | 84 | PR and issues reporting are always welcome :) 85 | 86 | ### License 87 | 88 | See LICENSE file 89 | 90 | ### Changelog 91 | 92 | See CHANGELOG.md file 93 | 94 | ### Thank you, community! 95 | 96 | All this wouldn't have been possible without these great [contributors](https://github.com/vesparny/angular-kickstart/graphs/contributors) and everybody who comes with new ideas and suggestions. 97 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-kickstart", 3 | "dependencies": { 4 | "normalize-css": "~3.0.3", 5 | "angular": "~1.3.0", 6 | "angular-ui-router": "~0.2.14", 7 | "pure": "~0.5.0" 8 | }, 9 | "devDependencies": { 10 | "angular-mocks": "~1.3.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /build/build.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | //basic configuration object used by gulp tasks 4 | module.exports = { 5 | port: 3000, 6 | uiPort: 3001, 7 | tmp: 'build/tmp', 8 | dist: 'build/dist', 9 | base: 'client', 10 | tpl: 'client/src/**/*.tpl.html', 11 | mainScss: 'client/src/scss/main.scss', 12 | scss: 'client/src/scss/**/*.scss', 13 | js: [ 14 | 'client/src/**/*.js', 15 | '!client/src/vendor/**/*.js', 16 | 'client/test/unit/**/*.js', 17 | 'client/test/e2e/**/*.js' 18 | ], 19 | index: 'client/index.html', 20 | assets: 'client/assets/**', 21 | images: 'client/assets/images/**/*', 22 | banner: ['/**', 23 | ' * <%= pkg.name %> - <%= pkg.description %>', 24 | ' * @version v<%= pkg.version %>', 25 | ' * @link <%= pkg.homepage %>', 26 | ' * @license <%= pkg.license %>', 27 | ' */', 28 | '' 29 | ].join('\n') 30 | }; 31 | -------------------------------------------------------------------------------- /build/karma.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var baseDir = 'client'; 4 | 5 | module.exports = { 6 | 7 | //This is the list of file patterns to load into the browser during testing. 8 | files: [ 9 | baseDir + '/src/vendor/angular/angular.js', 10 | baseDir + '/src/vendor/angular-mocks/angular-mocks.js', 11 | baseDir + '/src/vendor/angular-ui-router/release/angular-ui-router.js', 12 | baseDir + '/src/app/**/*.js', 13 | baseDir + '/src/common/**/*.js', 14 | 'build/tmp/*.js', 15 | baseDir + '/test/unit/**/*.spec.js' 16 | ], 17 | 18 | //used framework 19 | frameworks: ['jasmine'], 20 | 21 | plugins: [ 22 | 'karma-chrome-launcher', 23 | 'karma-phantomjs-launcher', 24 | 'karma-jasmine', 25 | 'karma-coverage', 26 | 'karma-html-reporter', 27 | 'karma-mocha-reporter' 28 | ], 29 | 30 | preprocessors: { 31 | '**/client/src/**/*.js': 'coverage' 32 | }, 33 | 34 | reporters: ['mocha', 'html', 'coverage'], 35 | 36 | coverageReporter: { 37 | type: 'html', 38 | dir: baseDir + '/test/unit-results/coverage', 39 | file: 'coverage.html' 40 | }, 41 | 42 | htmlReporter: { 43 | outputDir: baseDir + '//test/unit-results/html' 44 | }, 45 | 46 | logLevel: 'info', 47 | 48 | urlRoot: '/__test/', 49 | 50 | //used browsers (overriding in some gulp task) 51 | browsers: ['PhantomJS'] 52 | }; 53 | -------------------------------------------------------------------------------- /build/protractor.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var baseDir = 'client'; 4 | //this is the port the application is running on 5 | var port = 3000; 6 | 7 | exports.config = { 8 | jasmineNodeOpts: { 9 | showColors: true, 10 | defaultTimeoutInterval: 30000 11 | }, 12 | 13 | specs: [ 14 | baseDir + '/test/e2e/**/*.scenario.js' 15 | ], 16 | 17 | capabilities: { 18 | 'browserName': 'chrome' 19 | }, 20 | seleniumArgs: ['-browserTimeout=60'], 21 | baseUrl: 'http://127.0.0.1:'+port 22 | }; 23 | -------------------------------------------------------------------------------- /client/apple-touch-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vesparny/angular-kickstart/c7328ab698a72749f91102097ce564f3027f3cd8/client/apple-touch-icon-precomposed.png -------------------------------------------------------------------------------- /client/assets/images/angular-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vesparny/angular-kickstart/c7328ab698a72749f91102097ce564f3027f3cd8/client/assets/images/angular-logo.png -------------------------------------------------------------------------------- /client/assets/images/bower-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vesparny/angular-kickstart/c7328ab698a72749f91102097ce564f3027f3cd8/client/assets/images/bower-logo.png -------------------------------------------------------------------------------- /client/assets/images/gulp-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vesparny/angular-kickstart/c7328ab698a72749f91102097ce564f3027f3cd8/client/assets/images/gulp-logo.png -------------------------------------------------------------------------------- /client/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vesparny/angular-kickstart/c7328ab698a72749f91102097ce564f3027f3cd8/client/favicon.ico -------------------------------------------------------------------------------- /client/humans.txt: -------------------------------------------------------------------------------- 1 | # humanstxt.org/ 2 | # The humans responsible & technology colophon 3 | 4 | # TEAM 5 | 6 | -- -- 7 | 8 | # THANKS 9 | 10 | 11 | 12 | # TECHNOLOGY COLOPHON 13 | 14 | HTML5, CSS3 15 | Normalize.css, AngularJS 16 | -------------------------------------------------------------------------------- /client/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | angular-kickstart 7 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 |
27 |
28 |
29 |
30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /client/src/app/app.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 'use strict'; 3 | 4 | angular.element(document).ready(function() { 5 | angular.bootstrap(document, ['app']); 6 | }); 7 | 8 | function config($stateProvider, $urlRouterProvider, $logProvider, $httpProvider) { 9 | $urlRouterProvider.otherwise('/'); 10 | $logProvider.debugEnabled(true); 11 | $httpProvider.interceptors.push('httpInterceptor'); 12 | $stateProvider 13 | .state('root', { 14 | views: { 15 | 'header': { 16 | templateUrl: 'src/common/header.tpl.html', 17 | controller: 'HeaderCtrl' 18 | }, 19 | 'footer': { 20 | templateUrl: 'src/common/footer.tpl.html', 21 | controller: 'FooterCtrl' 22 | } 23 | } 24 | }); 25 | } 26 | 27 | function MainCtrl($log) { 28 | $log.debug('MainCtrl laoded!'); 29 | } 30 | 31 | function run($log) { 32 | $log.debug('App is running!'); 33 | } 34 | 35 | angular.module('app', [ 36 | 'ui.router', 37 | 'home', 38 | 'getting-started', 39 | 'common.header', 40 | 'common.footer', 41 | 'common.services.data', 42 | 'common.directives.version', 43 | 'common.filters.uppercase', 44 | 'common.interceptors.http', 45 | 'templates' 46 | ]) 47 | .config(config) 48 | .run(run) 49 | .controller('MainCtrl', MainCtrl) 50 | .value('version', '1.1.0'); 51 | })(); 52 | -------------------------------------------------------------------------------- /client/src/app/getting-started/getting-started.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 'use strict'; 3 | 4 | /** 5 | * @name config 6 | * @description config block 7 | */ 8 | function config($stateProvider) { 9 | $stateProvider 10 | .state('root.getting-started', { 11 | url: '/getting-started', 12 | views: { 13 | '@': { 14 | templateUrl: 'src/app/getting-started/getting-started.tpl.html', 15 | controller: 'GettingStartedCtrl as docs' 16 | } 17 | } 18 | }); 19 | } 20 | 21 | /** 22 | * @name gettingStartedCtrl 23 | * @description Controller 24 | */ 25 | function GettingStartedCtrl($log) { 26 | var docs = this; 27 | docs.someMethos = function () { 28 | $log.debug('I\'m a method'); 29 | }; 30 | } 31 | 32 | angular.module('getting-started', []) 33 | .config(config) 34 | .controller('GettingStartedCtrl', GettingStartedCtrl); 35 | })(); 36 | -------------------------------------------------------------------------------- /client/src/app/getting-started/getting-started.tpl.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

4 | Note that this is only a getting started guide, for more detailed information about the build system, the available tasks, the configuration of the build or anything else, please refer to the documentation on the GitHub project. 5 |

6 | 7 |

What and Why

8 |

9 | angular-kickstart is an opinionated kickstart for single page application development with AngularJS. It makes your development and testing easy, keeps the structure of the project consistent and allows you to create a fully optimized 10 | production release withe ease. After having developed a lot of AngularJS projects I decided to collect here what I've learnt. 11 |

12 | 13 |

Getting started

14 |

15 | Install 16 | node.js. Then 17 | sass, gulp and bower if you haven't yet. 18 |

19 | 20 |
21 |     
22 |     $ gem install sass
23 |     $ npm -g install gulp bower
24 |     
25 | 
26 | 27 |

28 | After that, install 29 | angular-kickstart - download the latest release (or clone the master branch if want to run the development version). Unzip the project and cd into it, then 30 | install bower and npm dependencies, and run the application in development mode. 31 |

32 | 33 |
34 |     
35 |     $ npm install
36 |     $ bower install
37 |     $ gulp serve
38 |     
39 | 
40 | 41 |

42 | You are now ready to go, your applcation is available at http://127.0.0.1:3000. 43 |

44 |

45 | You are now ready to start coding, every file you add, edit or delete into the 46 | /client folder, will be handled by the build system and the browser will reload. 47 |

48 |

49 | When you are ready to build a production release there is a task for that. 50 |

51 | 52 |
53 |     
54 |     $ gulp serve:dist
55 |     
56 | 
57 | 58 |

59 | This task will lint your code, optimize css js and images files, run unit tests. After the task has successfully finished, you can find an optimized version of your project in the 60 | /build/dist folder. 61 |

62 | 63 |

64 | Other tasks are available: 65 |

66 | 67 |
68 |     
69 |     #for developing running unit test on every file change.
70 |     $ gulp serve:tdd
71 | 
72 |     #for running e2e test. (you application should be running on http://127.0.0.1:3000)
73 |     $ gulp test:e2e
74 | 
75 |     #for running unit tests one time then exit.
76 |     $ gulp test:unit
77 |     
78 | 
79 |

80 | 81 | Full documentation on GitHub 82 | 83 |

84 | 85 |
86 |
87 | 88 | -------------------------------------------------------------------------------- /client/src/app/home/home.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 'use strict'; 3 | 4 | /** 5 | * @name config 6 | * @description config block 7 | */ 8 | function config($stateProvider) { 9 | $stateProvider 10 | .state('root.home', { 11 | url: '/', 12 | views: { 13 | '@': { 14 | templateUrl: 'src/app/home/home.tpl.html', 15 | controller: 'HomeCtrl as home', 16 | resolve: { 17 | data: function(DataService) { 18 | return DataService.get(); 19 | } 20 | } 21 | } 22 | } 23 | }); 24 | } 25 | 26 | /** 27 | * @name HomeCtrl 28 | * @description Controller 29 | */ 30 | function HomeCtrl(data) { 31 | var home = this; 32 | home.data = data.data; 33 | } 34 | 35 | angular.module('home', []) 36 | .config(config) 37 | .controller('HomeCtrl', HomeCtrl); 38 | })(); 39 | -------------------------------------------------------------------------------- /client/src/app/home/home.tpl.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Speed up your AngularJS development with a complete and scalable build system that scaffolds the project for you. Just focus on writing code and tests, 4 | angular-kickstart will take care of the rest.

5 |
6 | 14 |
15 |
16 |
    17 |
  • 18 | 19 |
  • 20 |
  • 21 | 22 |
  • 23 |
  • 24 | Tweet 25 |
  • 26 |
27 |
28 | 29 |
30 |
31 |
32 |
33 | 34 |
35 |

AngularJS

36 |

The best JavaScript framework out there will power up your awesome app. 37 |

38 |
39 | 40 |
41 |
42 | 43 |
44 |

Gulpjs

45 |

A smart and scalable gulpjs based build system will take care of your development and testing workflow, as well as the optimization process for production release. Read more... 46 |

47 |
48 | 49 |
50 |
51 | 52 |
53 |

Bower

54 |

Bower will handle your front-end dependencies.

55 |
56 | 57 |
58 | 59 |
60 |
61 |

Sass + SMACSS

62 |

Sass is the most mature, stable, and powerful professional grade CSS extension language. The project is structured following the SMACSS architecture. 63 | Write your CSS in a modular and scalable way, the build system will compile your .scss files into a single css files. It should be easy to integrate less, stylus or any other preprocessor if you prefer. Pure is the default CSS framework, by you can easily plug your own.

64 |
65 | 66 |
67 |

Modular Structure

68 |

angular-kickstart comes with a 69 | by-feature files organization, keeping your code organized, especially if you are working on a large code-base. If you don't like it, just use your preferred structure, and the build system will still work. The code is written following best practices that make you able to write consistent code. Read more... 70 |

71 |
72 | 73 |
74 |

Keep Your Code Reusable

75 |

Every general purpose directive, service or filter, should be placed into the common directory, in this way you can copy and paste the directory into another project, require the module you need, and you are ready to go with your new project. 76 |

77 |
78 |
79 | 80 |
81 |
82 |

Unit testing

83 |

The build system comes with a special task for running tests by using Karma Test Runner. 84 |

85 |
86 | 87 |
88 |

e2e testing

89 |

end-to-end testing support is provided by the build system. Tests can be executed using protractor.

90 |
91 | 92 |
93 |

Build for production with ease

94 |

Easily optimize css js and images files for production.

95 |
96 |
97 | -------------------------------------------------------------------------------- /client/src/common/directives/version.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 'use strict'; 3 | 4 | function versionDirective(version) { 5 | return { 6 | restrict: 'A', 7 | /*jshint unused:false*/ 8 | link: function(scope, elm, attrs) { 9 | elm.text(version); 10 | } 11 | }; 12 | } 13 | 14 | angular.module('common.directives.version', []) 15 | .directive('appVersion', versionDirective); 16 | })(); 17 | -------------------------------------------------------------------------------- /client/src/common/filters/uppercase.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 'use strict'; 3 | 4 | function uppercase() { 5 | return function(text) { 6 | return text ? text.toUpperCase() : text; 7 | }; 8 | } 9 | 10 | angular.module('common.filters.uppercase', []) 11 | .filter('uppercase', uppercase); 12 | })(); 13 | -------------------------------------------------------------------------------- /client/src/common/footer.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 'use strict'; 3 | 4 | function footerCtrl($log) { 5 | $log.debug('Footer loaded'); 6 | } 7 | 8 | angular.module('common.footer', []) 9 | .controller('FooterCtrl', footerCtrl); 10 | })(); 11 | -------------------------------------------------------------------------------- /client/src/common/footer.tpl.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

© 2014 - Alessandro Arnodo. 4 |

5 |
6 | 16 |
17 |
18 | -------------------------------------------------------------------------------- /client/src/common/header.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 'use strict'; 3 | 4 | function headerCtrl($log) { 5 | $log.debug('Header loaded'); 6 | } 7 | 8 | angular.module('common.header', []) 9 | .controller('HeaderCtrl', headerCtrl); 10 | })(); 11 | -------------------------------------------------------------------------------- /client/src/common/header.tpl.html: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /client/src/common/interceptors/httpInterceptor.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 'use strict'; 3 | 4 | function httpInterceptor($q, $log) { 5 | return { 6 | request: function(config) { 7 | return config; 8 | }, 9 | requestError: function(rejection) { 10 | $log.debug(rejection); 11 | return $q.reject(rejection); 12 | }, 13 | response: function(response) { 14 | $log.debug('response: ', response); 15 | return response; 16 | }, 17 | responseError: function(rejection) { 18 | $log.debug(rejection); 19 | return $q.reject(rejection); 20 | } 21 | }; 22 | } 23 | 24 | angular.module('common.interceptors.http', []) 25 | .factory('httpInterceptor', httpInterceptor); 26 | })(); 27 | -------------------------------------------------------------------------------- /client/src/common/services/dataService.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 'use strict'; 3 | 4 | function dataService() { 5 | return { 6 | get: function() { 7 | return ['some', 'data']; 8 | } 9 | }; 10 | } 11 | 12 | angular.module('common.services.data', []) 13 | .factory('DataService', dataService); 14 | })(); 15 | -------------------------------------------------------------------------------- /client/src/scss/_base.scss: -------------------------------------------------------------------------------- 1 | //@import 'normalize'; 2 | 3 | /* Fonts 4 | ========================================================================== */ 5 | @import url(http://fonts.googleapis.com/css?family=Open+Sans:400); 6 | html, 7 | button, 8 | input, 9 | select, 10 | textarea, 11 | .pure-g [class *= "pure-u"] { 12 | font-family: 'Open Sans', sans-serif; 13 | 14 | } 15 | /* Defaults 16 | ========================================================================== */ 17 | 18 | html { 19 | @include font-size($base-root-size); 20 | line-height: 1.5; 21 | } 22 | ::-moz-selection { 23 | 24 | @include selection(); 25 | } 26 | ::selection { 27 | 28 | @include selection(); 29 | } 30 | ::-webkit-input-placeholder { 31 | 32 | @include placeholder(); 33 | } 34 | ::-moz-placeholder { 35 | 36 | @include placeholder(); 37 | } 38 | :-ms-input-placeholder { 39 | @include placeholder(); 40 | 41 | } 42 | img.pure-img { 43 | vertical-align: middle; 44 | max-width: 60%; 45 | display: inline; 46 | 47 | } 48 | code { 49 | color: $red; 50 | 51 | } 52 | h3 { 53 | font-weight: normal; 54 | @include font-size(22); 55 | 56 | } 57 | .pure-menu.pure-menu-horizontal { 58 | background: $silver; 59 | 60 | } 61 | a { 62 | color: $blue; 63 | text-decoration: none; 64 | line-height: inherit; 65 | } 66 | a:focus, 67 | a:hover { 68 | color: darken($blue, 9); 69 | 70 | } 71 | a.pure-button:focus, 72 | a.pure-button:hover { 73 | color: #fff; 74 | 75 | } 76 | pre { 77 | code { 78 | color: $black; 79 | background-color: $silver; 80 | border-width: 1px; 81 | border-style: solid; 82 | border-color: $gray; 83 | display: block; 84 | padding: 0.5em; 85 | } 86 | 87 | } 88 | h4 { 89 | @include font-size(21); 90 | } 91 | -------------------------------------------------------------------------------- /client/src/scss/_helpers.scss: -------------------------------------------------------------------------------- 1 | %center { 2 | margin-right: auto; 3 | margin-left: auto; 4 | } 5 | 6 | %text-center { 7 | text-align:center; 8 | } 9 | 10 | %clearfix { 11 | &::before, 12 | &::after { 13 | content: ""; 14 | display: table; 15 | } 16 | &::after { 17 | clear: both; 18 | } 19 | } 20 | 21 | .text-center{ 22 | @extend %text-center; 23 | } 24 | -------------------------------------------------------------------------------- /client/src/scss/_mixins.scss: -------------------------------------------------------------------------------- 1 | //rem font-size with px fallback 2 | @mixin font-size( $value ) { 3 | font-size: ( $value ) * 1px; 4 | font-size: ( $value / $base-font-size ) * 1rem; 5 | } 6 | 7 | //box Sizing 8 | @mixin box-sizing ($type: border-box) { 9 | //content-box | border-box | inherit 10 | -webkit-box-sizing: $type; 11 | -moz-box-sizing: $type; 12 | box-sizing: $type; 13 | } 14 | @mixin border-box() { 15 | @include box-sizing( border-box ); 16 | } 17 | 18 | //reset border, margin, and padding 19 | @mixin box-reset() { 20 | margin: 0; 21 | padding: 0; 22 | border: 0 none; 23 | } 24 | 25 | //px to rem sizing with px fallout 26 | @mixin font-size($size, $context: $base-root-size) { 27 | font-size: $size + px; 28 | font-size: ($size / $base-root-size) + rem; 29 | } 30 | 31 | //selection 32 | @mixin selection() { 33 | background: #b3d4fc; 34 | text-shadow: none; 35 | } 36 | 37 | //placeholder 38 | @mixin placeholder() { 39 | color: #999; 40 | } 41 | 42 | //vertical align (http://zerosixthree.se/vertical-align-anything-with-just-3-lines-of-css/) 43 | @mixin vertical-align { 44 | position: relative; 45 | top: 50%; 46 | -webkit-transform: translateY(-50%); 47 | -ms-transform: translateY(-50%); 48 | transform: translateY(-50%); 49 | } 50 | -------------------------------------------------------------------------------- /client/src/scss/_settings.scss: -------------------------------------------------------------------------------- 1 | // Base font size in used in _mixins.scss 2 | $base-root-size: 16; 3 | 4 | //colors https://github.com/mrmrs/colors/blob/master/sass/_variables.scss 5 | $aqua: #7fdbff; 6 | $blue: #0074d9; 7 | $navy: #001f3f; 8 | $teal: #39cccc; 9 | $green: #2ecc40; 10 | $olive: #3d9970; 11 | $lime: #01ff70; 12 | 13 | // Warm 14 | $yellow: #ffdc00; 15 | $orange: #ff851b; 16 | $red: #ff4136; 17 | $fuchsia: #f012be; 18 | $purple: #b10dc9; 19 | $maroon: #85144b; 20 | 21 | // Gray Scale 22 | $white: #fff; 23 | $silver: #ddd; 24 | $gray: #aaa; 25 | $black: #111; 26 | -------------------------------------------------------------------------------- /client/src/scss/_states.scss: -------------------------------------------------------------------------------- 1 | //states here 2 | -------------------------------------------------------------------------------- /client/src/scss/layouts/_page.scss: -------------------------------------------------------------------------------- 1 | .l-page { 2 | .pure-g > div { 3 | @include box-sizing(); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /client/src/scss/main.scss: -------------------------------------------------------------------------------- 1 | /* 2 | inspired by: 3 | https://github.com/minamarkham/sassy-starter/ 4 | https://github.com/kachunchau/smacss-boilerplate 5 | https://github.com/davidrapson/scss-toolkit 6 | */ 7 | @import 'settings', 'mixins', 'base', 'helpers', 'modules/island','modules/horizontal-list', 'modules/buttons', 'layouts/page', 'states'; 8 | -------------------------------------------------------------------------------- /client/src/scss/modules/_buttons.scss: -------------------------------------------------------------------------------- 1 | .button-xsmall { 2 | font-size: 70%; 3 | 4 | } 5 | .button-small { 6 | font-size: 85%; 7 | 8 | } 9 | .button-large { 10 | font-size: 110%; 11 | 12 | } 13 | .button-xlarge { 14 | font-size: 125%; 15 | } 16 | 17 | .button-expanded { 18 | width: 100%; 19 | padding:1rem 0; 20 | margin:3px; 21 | } 22 | -------------------------------------------------------------------------------- /client/src/scss/modules/_horizontal-list.scss: -------------------------------------------------------------------------------- 1 | .hlist { 2 | list-style: none; 3 | @extend %text-center; 4 | @include box-reset(); 5 | padding: 0 0 2em 0; 6 | >li { 7 | display: inline-block; 8 | margin-left: 1em; 9 | a.tweet { 10 | position:relative; 11 | top:-3px; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /client/src/scss/modules/_island.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Island module that adds padding. 3 | */ 4 | 5 | .island { 6 | padding: 1em; 7 | 8 | } 9 | .island3 { 10 | padding: 3em; 11 | 12 | } 13 | .island-panel { 14 | background-color: $silver; 15 | padding: 2em; 16 | @include font-size(20); 17 | } 18 | -------------------------------------------------------------------------------- /client/test/e2e/01.home.scenario.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /*jshint undef:false */ 4 | (function() { 5 | var utils = require('../utils'); 6 | describe('app', function() { 7 | beforeEach(function() { 8 | console.info('\nrunning:', jasmine.getEnv().currentSpec.description); 9 | }); 10 | 11 | afterEach(function() { 12 | if (!jasmine.getEnv().currentSpec.results().passed()) { 13 | utils.takeScreenshot(browser, jasmine.getEnv().currentSpec.description.replace(/ /g, '-')); 14 | } 15 | }); 16 | 17 | it('should load the homepage', function() { 18 | browser.get('/'); 19 | expect(browser.isElementPresent(by.css('body'))).toBe(true); 20 | }); 21 | 22 | it('should navigate to the docs page when clicking', function() { 23 | element(by.css('a[ui-sref="root.getting-started"]')).click(); 24 | expect(browser.getCurrentUrl()).toMatch(/\/getting-started/); 25 | }); 26 | 27 | }); 28 | })(); 29 | -------------------------------------------------------------------------------- /client/test/screenshots/README.md: -------------------------------------------------------------------------------- 1 | ###Screenshots of failing tests will be placed in this folder. 2 | -------------------------------------------------------------------------------- /client/test/unit-results/README.md: -------------------------------------------------------------------------------- 1 | ###A coverage report will be generated by karma. 2 | -------------------------------------------------------------------------------- /client/test/unit/app/app.spec.js: -------------------------------------------------------------------------------- 1 | /* jshint undef:false*/ 2 | (function() { 3 | 'use strict'; 4 | 5 | describe('app module', function() { 6 | var module; 7 | var deps; 8 | 9 | var hasModule = function(m) { 10 | return deps.indexOf(m) >= 0; 11 | }; 12 | 13 | beforeEach(function() { 14 | module = angular.module('app'); 15 | deps = module.value('app').requires; 16 | }); 17 | 18 | it('should be registered', function() { 19 | expect(module).not.toEqual(null); 20 | }); 21 | 22 | it('should have ui.router as a dependency', function() { 23 | expect(hasModule('ui.router')).toEqual(true); 24 | }); 25 | 26 | it('should have common.services.data as a dependency', function() { 27 | expect(hasModule('common.services.data')).toEqual(true); 28 | }); 29 | }); 30 | })(); 31 | -------------------------------------------------------------------------------- /client/test/unit/app/home/home.spec.js: -------------------------------------------------------------------------------- 1 | /* jshint undef:false*/ 2 | (function() { 3 | 'use strict'; 4 | 5 | describe('HomeCtrl', function() { 6 | var rootScope; 7 | var fakeData = ['some', 'data']; 8 | var ctrl; 9 | var scope; 10 | 11 | beforeEach(module('app')); 12 | beforeEach(inject(function($rootScope, $controller) { 13 | rootScope = $rootScope; 14 | scope = $rootScope.$new(); 15 | ctrl = $controller('HomeCtrl as home', { 16 | $scope: scope, 17 | data: { 18 | data: fakeData 19 | } 20 | }); 21 | })); 22 | 23 | it('should not be null', function() { 24 | expect(ctrl).not.toEqual(null); 25 | }); 26 | 27 | it('should have "data" into its $scope', function() { 28 | expect(scope.home.data[0]).toEqual('some'); 29 | expect(scope.home.data[1]).toEqual('data'); 30 | expect(scope.home.data.length).toEqual(2); 31 | }); 32 | }); 33 | })(); 34 | -------------------------------------------------------------------------------- /client/test/unit/common/directives/version.spec.js: -------------------------------------------------------------------------------- 1 | /* jshint undef:false*/ 2 | (function() { 3 | 'use strict'; 4 | 5 | describe('Directive: version', function() { 6 | 7 | var compile; 8 | var rootScope; 9 | 10 | beforeEach(module('common.directives.version')); 11 | beforeEach(function() { 12 | module(function($provide) { 13 | //mocking version value 14 | $provide.value('version', 'test'); 15 | }); 16 | }); 17 | 18 | beforeEach(inject(function($compile, $rootScope) { 19 | compile = $compile; 20 | rootScope = $rootScope; 21 | })); 22 | 23 | it('should display the version number', function() { 24 | var element = compile('
')(rootScope); 25 | expect(element.html()).toMatch(/test/i); 26 | }); 27 | 28 | 29 | 30 | 31 | }); 32 | })(); 33 | -------------------------------------------------------------------------------- /client/test/unit/common/filters/uppercase.spec.js: -------------------------------------------------------------------------------- 1 | /* jshint undef:false*/ 2 | (function() { 3 | 'use strict'; 4 | 5 | describe('Filters: uppercase', function() { 6 | 7 | var filter; 8 | beforeEach(module('common.filters.uppercase')); 9 | beforeEach(inject(function($filter) { 10 | filter = $filter; 11 | })); 12 | 13 | it('should create an uppercase string', function() { 14 | expect(filter('uppercase')('hello')).toEqual('HELLO'); 15 | }); 16 | }); 17 | })(); 18 | -------------------------------------------------------------------------------- /client/test/utils.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var fs = require('fs'); 3 | 4 | exports.takeScreenshot = function(browser, filename) { 5 | browser.takeScreenshot().then(function(png) { 6 | fs.writeFileSync('./client/test/screenshots/' + filename + '.png', png, 'base64'); 7 | }); 8 | }; 9 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var config = require('./build/build.config.js'); 4 | var karmaConfig = require('./build/karma.config.js'); 5 | var protractorConfig = require('./build/protractor.config.js'); 6 | var gulp = require('gulp'); 7 | var $ = require('gulp-load-plugins')(); 8 | var runSequence = require('run-sequence'); 9 | var browserSync = require('browser-sync'); 10 | var reload = browserSync.reload; 11 | var pkg = require('./package'); 12 | var karma = require('karma').server; 13 | var del = require('del'); 14 | var _ = require('lodash'); 15 | /* jshint camelcase:false*/ 16 | var webdriverStandalone = require('gulp-protractor').webdriver_standalone; 17 | var webdriverUpdate = require('gulp-protractor').webdriver_update; 18 | 19 | //update webdriver if necessary, this task will be used by e2e task 20 | gulp.task('webdriver:update', webdriverUpdate); 21 | 22 | // run unit tests and watch files 23 | gulp.task('tdd', function(cb) { 24 | karma.start(_.assign({}, karmaConfig, { 25 | singleRun: false, 26 | action: 'watch', 27 | browsers: ['PhantomJS'] 28 | }), cb); 29 | }); 30 | 31 | // run unit tests with travis CI 32 | gulp.task('travis', ['build'], function(cb) { 33 | karma.start(_.assign({}, karmaConfig, { 34 | singleRun: true, 35 | browsers: ['PhantomJS'] 36 | }), cb); 37 | }); 38 | 39 | // optimize images and put them in the dist folder 40 | gulp.task('images', function() { 41 | return gulp.src(config.images) 42 | .pipe($.imagemin({ 43 | progressive: true, 44 | interlaced: true 45 | })) 46 | .pipe(gulp.dest(config.dist + '/assets/images')) 47 | .pipe($.size({ 48 | title: 'images' 49 | })); 50 | }); 51 | 52 | //generate angular templates using html2js 53 | gulp.task('templates', function() { 54 | return gulp.src(config.tpl) 55 | .pipe($.changed(config.tmp)) 56 | .pipe($.html2js({ 57 | outputModuleName: 'templates', 58 | base: 'client', 59 | useStrict: true 60 | })) 61 | .pipe($.concat('templates.js')) 62 | .pipe(gulp.dest(config.tmp)) 63 | .pipe($.size({ 64 | title: 'templates' 65 | })); 66 | }); 67 | 68 | //generate css files from scss sources 69 | gulp.task('sass', function() { 70 | return gulp.src(config.mainScss) 71 | .pipe($.sass()) 72 | .on('error', $.sass.logError) 73 | .pipe(gulp.dest(config.tmp)) 74 | .pipe($.size({ 75 | title: 'sass' 76 | })); 77 | }); 78 | 79 | //build files for creating a dist release 80 | gulp.task('build:dist', ['clean'], function(cb) { 81 | runSequence(['jshint', 'build', 'copy', 'copy:assets', 'images', 'test:unit'], 'html', cb); 82 | }); 83 | 84 | //build files for development 85 | gulp.task('build', ['clean'], function(cb) { 86 | runSequence(['sass', 'templates'], cb); 87 | }); 88 | 89 | //generate a minified css files, 2 js file, change theirs name to be unique, and generate sourcemaps 90 | gulp.task('html', function() { 91 | var assets = $.useref.assets({ 92 | searchPath: '{build,client}' 93 | }); 94 | 95 | return gulp.src(config.index) 96 | .pipe(assets) 97 | .pipe($.sourcemaps.init()) 98 | .pipe($.if('**/*main.js', $.ngAnnotate())) 99 | .pipe($.if('*.js', $.uglify({ 100 | mangle: false, 101 | }))) 102 | .pipe($.if('*.css', $.csso())) 103 | .pipe($.if(['**/*main.js', '**/*main.css'], $.header(config.banner, { 104 | pkg: pkg 105 | }))) 106 | .pipe($.rev()) 107 | .pipe(assets.restore()) 108 | .pipe($.useref()) 109 | .pipe($.revReplace()) 110 | .pipe($.if('*.html', $.minifyHtml({ 111 | empty: true 112 | }))) 113 | .pipe($.sourcemaps.write()) 114 | .pipe(gulp.dest(config.dist)) 115 | .pipe($.size({ 116 | title: 'html' 117 | })); 118 | }); 119 | 120 | //copy assets in dist folder 121 | gulp.task('copy:assets', function() { 122 | return gulp.src(config.assets, { 123 | dot: true 124 | }).pipe(gulp.dest(config.dist + '/assets')) 125 | .pipe($.size({ 126 | title: 'copy:assets' 127 | })); 128 | }); 129 | 130 | //copy assets in dist folder 131 | gulp.task('copy', function() { 132 | return gulp.src([ 133 | config.base + '/*', 134 | '!' + config.base + '/*.html', 135 | '!' + config.base + '/src', 136 | '!' + config.base + '/test' 137 | ]).pipe(gulp.dest(config.dist)) 138 | .pipe($.size({ 139 | title: 'copy' 140 | })); 141 | }); 142 | 143 | //clean temporary directories 144 | gulp.task('clean', del.bind(null, [config.dist, config.tmp])); 145 | 146 | //lint files 147 | gulp.task('jshint', function() { 148 | return gulp.src(config.js) 149 | .pipe(reload({ 150 | stream: true, 151 | once: true 152 | })) 153 | .pipe($.jshint()) 154 | .pipe($.jshint.reporter('jshint-stylish')) 155 | .pipe($.if(!browserSync.active, $.jshint.reporter('fail'))); 156 | }); 157 | 158 | /* tasks supposed to be public */ 159 | 160 | 161 | //default task 162 | gulp.task('default', ['serve']); // 163 | 164 | //run unit tests and exit 165 | gulp.task('test:unit', ['build'], function(cb) { 166 | karma.start(_.assign({}, karmaConfig, { 167 | singleRun: true 168 | }), cb); 169 | }); 170 | 171 | // Run e2e tests using protractor, make sure serve task is running. 172 | gulp.task('test:e2e', ['webdriver:update'], function() { 173 | return gulp.src(protractorConfig.config.specs) 174 | .pipe($.protractor.protractor({ 175 | configFile: 'build/protractor.config.js' 176 | })) 177 | .on('error', function(e) { 178 | throw e; 179 | }); 180 | }); 181 | 182 | //run the server, watch for file changes and redo tests. 183 | gulp.task('serve:tdd', function(cb) { 184 | runSequence(['serve', 'tdd'], cb); 185 | }); 186 | 187 | //run the server after having built generated files, and watch for changes 188 | gulp.task('serve', ['build'], function() { 189 | browserSync({ 190 | port: config.port, 191 | ui: { 192 | port: config.uiPort 193 | }, 194 | notify: false, 195 | logPrefix: pkg.name, 196 | server: ['build', 'client'] 197 | }); 198 | 199 | gulp.watch(config.html, reload); 200 | gulp.watch(config.scss, ['sass', reload]); 201 | gulp.watch(config.js, ['jshint']); 202 | gulp.watch(config.tpl, ['templates', reload]); 203 | gulp.watch(config.assets, reload); 204 | }); 205 | 206 | //run the app packed in the dist folder 207 | gulp.task('serve:dist', ['build:dist'], function() { 208 | browserSync({ 209 | port: config.port, 210 | ui: { 211 | port: config.uiPort 212 | }, 213 | notify: false, 214 | server: [config.dist] 215 | }); 216 | }); 217 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": "Alessandro Arnodo", 3 | "name": "angular-kickstart", 4 | "email": "alessandro@arnodo.net", 5 | "url": "http://alessandro.arnodo.net", 6 | "version": "1.1.0", 7 | "homepage": "https://github.com/vesparny/angular-kickstart", 8 | "description": "Speed up your AngularJS development whith a great build system.", 9 | "license": "MIT", 10 | "bugs": "https://github.com/vesparny/angular-kickstart/issues", 11 | "repository": { 12 | "type": "git", 13 | "url": "git@github.com:vesparny/angular-kickstart.git" 14 | }, 15 | "devDependencies": { 16 | "browser-sync": "~2.7.1", 17 | "del": "~1.1.1", 18 | "gulp": "~3.8.11", 19 | "gulp-changed": "~1.2.1", 20 | "gulp-concat": "~2.5.2", 21 | "gulp-csso": "~1.0.0", 22 | "gulp-header": "~1.2.2", 23 | "gulp-html2js": "~0.2.0", 24 | "gulp-if": "~1.2.5", 25 | "gulp-imagemin": "~2.2.1", 26 | "gulp-jshint": "~1.10.0", 27 | "gulp-load-plugins": "~0.10.0", 28 | "gulp-minify-html": "~1.0.2", 29 | "gulp-ng-annotate": "~0.5.3", 30 | "gulp-ng-html2js": "~0.2.0", 31 | "gulp-protractor": "1.0.0", 32 | "gulp-rev": "~3.0.1", 33 | "gulp-rev-replace": "~0.4.0", 34 | "gulp-sass": "~2.0.0", 35 | "gulp-size": "~1.2.1", 36 | "gulp-sourcemaps": "~1.5.2", 37 | "gulp-uglify": "~1.2.0", 38 | "gulp-useref": "~1.1.2", 39 | "jshint-stylish": "~1.0.2", 40 | "karma": "~0.12.31", 41 | "karma-chrome-launcher": "~0.1.8", 42 | "karma-coverage": "~0.3.1", 43 | "karma-html-reporter": "~0.2.6", 44 | "karma-jasmine": "~0.3.5", 45 | "karma-mocha-reporter": "~1.0.2", 46 | "karma-phantomjs-launcher": "~0.1.4", 47 | "lodash": "~3.8.0", 48 | "protractor": "~2.0.0", 49 | "run-sequence": "~1.1.0" 50 | }, 51 | "engines": { 52 | "node": ">=0.10.x" 53 | }, 54 | "scripts": { 55 | "test": "gulp travis" 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /server/README.md: -------------------------------------------------------------------------------- 1 | ###This would be a good location for your server-side code. 2 | --------------------------------------------------------------------------------