1 var lrSnippet = require('connect-livereload')();
\r
2 var mountFolder = function (connect, dir) {
\r
3 return connect.static(require('path').resolve(dir));
\r
6 module.exports = function ( grunt ) {
\r
9 * Load required Grunt tasks. These are installed based on the versions listed
\r
10 * in `package.json` when you do `npm install` in this directory.
\r
12 grunt.loadNpmTasks('grunt-contrib-clean');
\r
13 grunt.loadNpmTasks('grunt-contrib-copy');
\r
14 grunt.loadNpmTasks('grunt-contrib-jshint');
\r
15 grunt.loadNpmTasks('grunt-contrib-concat');
\r
16 grunt.loadNpmTasks('grunt-contrib-watch');
\r
17 grunt.loadNpmTasks('grunt-contrib-uglify');
\r
18 grunt.loadNpmTasks('grunt-conventional-changelog');
\r
19 grunt.loadNpmTasks('grunt-bump');
\r
20 //grunt.loadNpmTasks('grunt-recess');
\r
21 grunt.loadNpmTasks('grunt-shell');
\r
22 grunt.loadNpmTasks('grunt-karma');
\r
23 grunt.loadNpmTasks('grunt-ng-annotate');
\r
24 grunt.loadNpmTasks('grunt-html2js');
\r
25 grunt.loadNpmTasks('grunt-contrib-less');
\r
26 grunt.loadNpmTasks('grunt-contrib-connect');
\r
27 grunt.loadNpmTasks('grunt-open');
\r
28 grunt.loadNpmTasks('grunt-replace');
\r
31 * Load in our build configuration file.
\r
33 var userConfig = require( './build.config.js' );
\r
42 json: grunt.file.readJSON('./config/development.json')
\r
50 src: ['./config/env.module.js'],
\r
51 dest: 'src/common/config/'
\r
59 json: grunt.file.readJSON('./config/production.json')
\r
67 src: ['./config/env.module.js'],
\r
68 dest: 'src/common/config/'
\r
76 * This is the configuration object Grunt uses to give each plugin its
\r
81 * We read in our `package.json` file so we can access the package name and
\r
82 * version. It's already there, so we don't repeat ourselves here.
\r
84 pkg: grunt.file.readJSON("package.json"),
\r
87 * The banner is the comment that is placed at the top of our compiled
\r
88 * source files. It is first processed as a Grunt template, where the `<%=`
\r
89 * pairs are evaluated based on this very configuration object.
\r
94 ' * <%= pkg.name %> - v<%= pkg.version %> - <%= grunt.template.today("yyyy-mm-dd") %>\n' +
\r
95 ' * <%= pkg.homepage %>\n' +
\r
97 ' * Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author %>\n' +
\r
98 ' * Licensed <%= pkg.licenses.type %> <<%= pkg.licenses.url %>>\n' +
\r
103 * Creates a changelog on a new version.
\r
107 dest: 'CHANGELOG.md',
\r
108 template: 'changelog.tpl'
\r
113 * Increments the version number, etc.
\r
122 commitMessage: 'chore(release): v%VERSION%',
\r
125 "client/bower.json"
\r
128 tagName: 'v%VERSION%',
\r
129 tagMessage: 'Version %VERSION%',
\r
136 * The directories to delete when `grunt clean` is executed.
\r
139 '<%= build_dir %>',
\r
140 '<%= compile_dir %>'
\r
144 * The `copy` task just copies files from A to B. We use it here to copy
\r
145 * our project assets (images, fonts, etc.) and javascripts into
\r
146 * `build_dir`, and then to copy the assets to `compile_dir`.
\r
149 build_app_assets: {
\r
153 dest: '<%= build_dir %>/assets/',
\r
159 build_vendor_assets: {
\r
162 src: [ '<%= vendor_files.assets %>' ],
\r
163 dest: '<%= build_dir %>/assets/',
\r
173 src: [ '<%= app_files.js %>', '<%= app_files.css %>', '<%= app_files.lang %>' ],
\r
174 dest: '<%= build_dir %>/',
\r
183 src: ['<%= app_files.templates %>'],
\r
184 dest: '<%= build_dir %>/',
\r
193 src: [ '<%= vendor_files.js %>' ],
\r
194 dest: '<%= build_dir %>/',
\r
203 src: [ '<%= app_files.images %>' ],
\r
204 dest: '<%= build_dir %>/',
\r
210 build_vendorimages: {
\r
213 src: [ '<%= vendor_files.images %>' ],
\r
214 dest: '<%= build_dir %>/',
\r
223 src: [ '<%= vendor_files.css %>' ],
\r
224 dest: '<%= build_dir %>',
\r
234 dest: '<%= compile_dir %>/assets',
\r
235 cwd: '<%= build_dir %>/assets',
\r
245 dest: '<%= compile_dir %>/font',
\r
246 cwd: '<%= build_dir %>/font',
\r
254 * `grunt concat` concatenates multiple source files into a single file.
\r
258 * The `build_css` target concatenates compiled CSS and vendor CSS
\r
263 '<%= vendor_files.css %>',
\r
264 '<%= build_dir %>/assets/<%= pkg.name %>-<%= pkg.version %>.css'
\r
266 dest: '<%= build_dir %>/assets/<%= pkg.name %>-<%= pkg.version %>.css'
\r
269 * The `compile_js` target is the concatenation of our application source
\r
270 * code and all specified vendor source code into a single file.
\r
274 banner: '<%= meta.banner %>'
\r
277 '<%= vendor_files.js %>',
\r
279 '<%= build_dir %>/src/**/*.js',
\r
280 '<%= html2js.common.dest %>',
\r
281 '<%= html2js.app.dest %>',
\r
284 dest: '<%= compile_dir %>/assets/<%= pkg.name %>-<%= pkg.version %>.js'
\r
289 * `ng-min` annotates the sources before minifying. That is, it allows us
\r
290 * to code without the array syntax.
\r
299 src: [ '<%= app_files.js %>' ],
\r
300 cwd: '<%= build_dir %>',
\r
301 dest: '<%= build_dir %>',
\r
309 * Minify the sources!
\r
314 banner: '<%= meta.banner %>'
\r
317 '<%= concat.compile_js.dest %>': '<%= concat.compile_js.dest %>'
\r
323 * `less` less plugin handles the LESS compilation and minification automatically
\r
324 * this has been changed to the LESS plugin from recess plugin above because of
\r
325 * out of memory issues with the original plugin.
\r
331 paths: ["assets/css"],
\r
334 strictImports: true
\r
337 '<%= build_dir %>/assets/<%= pkg.name %>-<%= pkg.version %>.css': '<%= app_files.less %>'
\r
342 paths: ["assets/css"],
\r
347 '<%= build_dir %>/assets/<%= pkg.name %>-<%= pkg.version %>.css': '<%= app_files.less %>'
\r
353 * `jshint` defines the rules of our linter as well as which files we
\r
354 * should check. This file, all javascript sources, and all our unit tests
\r
355 * are linted based on the policies listed in `options`. But we can also
\r
356 * specify exclusionary patterns by prefixing them with an exclamation
\r
357 * point (!); this is useful when code comes from a third party but is
\r
358 * nonetheless inside `src/`.
\r
362 '<%= app_files.js %>',
\r
363 '<%= app_files.app_assets %>',
\r
366 '<%= app_files.jsunit %>'
\r
369 'OriginalGruntfile.js'
\r
385 * HTML2JS is a Grunt plugin that takes all of your template files and
\r
386 * places them into JavaScript files as strings that are added to
\r
387 * AngularJS's template cache. This means that the templates too become
\r
388 * part of the initial payload as one JavaScript file. Neat!
\r
392 * These are the templates from `src/app`.
\r
398 src: [ '<%= app_files.atpl %>' ],
\r
399 dest: '<%= build_dir %>/templates-app.js'
\r
403 * These are the templates from `src/common`.
\r
409 src: [ '<%= app_files.ctpl %>' ],
\r
410 dest: '<%= build_dir %>/templates-common.js'
\r
415 * The Karma configurations.
\r
419 configFile: '<%= build_dir %>/karma-unit.js'
\r
424 port: 9877 // IMPORTANT!
\r
428 browsers: ['PhantomJS']
\r
433 * The `index` task compiles the `index.html` file as a Grunt template. CSS
\r
434 * and JS files co-exist here but they get split apart later.
\r
439 * During development, we don't want to have wait for compilation,
\r
440 * concatenation, minification, etc. So to avoid these steps, we simply
\r
441 * add all script files directly to the `<head>` of `index.html`. The
\r
442 * `src` property contains the list of included files.
\r
445 dir: '<%= build_dir %>',
\r
447 '<%= html2js.common.dest %>',
\r
448 '<%= html2js.app.dest %>',
\r
449 '<%= vendor_files.css %>',
\r
450 '<%= build_dir %>/assets/<%= pkg.name %>-<%= pkg.version %>.css'
\r
455 * When it is time to have a completely compiled application, we can
\r
456 * alter the above to include only a single JavaScript and a single CSS
\r
457 * file. Now we're back!
\r
460 dir: '<%= compile_dir %>',
\r
462 '<%= concat.compile_js.dest %>',
\r
463 '<%= concat.build_css.dest %>'
\r
464 //'<%= recess.compile.dest %>'
\r
470 * This task compiles the karma template so that changes to its file array
\r
471 * don't have to be managed manually.
\r
475 dir: '<%= build_dir %>',
\r
477 '<%= vendor_files.js %>',
\r
478 '<%= html2js.app.dest %>',
\r
479 '<%= html2js.common.dest %>',
\r
480 '<%= app_files.js_common %>',
\r
481 '<%= app_files.js_app %>',
\r
482 '<%= app_files.jsunit %>'
\r
490 hostname: '0.0.0.0',
\r
491 middleware: function (connect) {
\r
493 mountFolder(connect, 'build'),
\r
501 hostname: '0.0.0.0',
\r
516 path: 'http://127.0.0.1:9000/'
\r
519 path: 'http://127.0.0.1:9001/'
\r
523 * And for rapid development, we have a watch set up that checks to see if
\r
524 * any of the files listed below change, and then to execute the listed
\r
525 * tasks when they do. This just saves us from having to type "grunt" into
\r
526 * the command-line every time we want to see what we're working on; we can
\r
527 * instead just leave "grunt watch" running in a background terminal. Set it
\r
528 * and forget it, as Ron Popeil used to tell us.
\r
530 * But we don't need the same thing to happen for all the files.
\r
534 * By default, we want the Live Reload to work for all tasks; this is
\r
535 * overridden in some tasks (like this file) where browser resources are
\r
536 * unaffected. It runs by default on port 35729, which your browser
\r
537 * plugin should auto-detect.
\r
544 * When the Gruntfile changes, we just want to lint it. In fact, when
\r
545 * your Gruntfile changes, it will automatically be reloaded!
\r
548 files: 'OriginalGruntfile.js',
\r
549 tasks: [ 'jshint:gruntfile' ],
\r
556 * When our JavaScript source files change, we want to run lint them and
\r
557 * run our unit tests.
\r
561 '<%= app_files.js %>', '<%= app_files.lang %>'
\r
563 tasks: [ 'jshint:src', 'karma:unit:run', 'copy:build_appjs' ]
\r
567 * When assets are changed, copy them. Note that this will *not* copy new
\r
568 * files, so this is probably not very useful.
\r
574 tasks: [ 'copy:build_app_assets' ]
\r
578 * When index.html changes, we need to compile it.
\r
581 files: [ '<%= app_files.html %>' ],
\r
582 tasks: [ 'index:build' ]
\r
586 * When our templates change, we only rewrite the template cache.
\r
590 '<%= app_files.atpl %>',
\r
591 '<%= app_files.ctpl %>'
\r
593 tasks: ['copy:copy_template']/*[ 'html2js' ]*/
\r
597 * When the CSS files change, we need to compile and minify them.
\r
600 files: [ 'src/**/*.less' ],
\r
601 tasks: [ 'less:development' ]
\r
605 * When a JavaScript unit test file changes, we only want to lint it and
\r
606 * run the unit tests. We don't want to do any live reloading.
\r
610 '<%= app_files.jsunit %>'
\r
612 tasks: [ 'jshint:test', 'karma:unit:run' ],
\r
620 command: "node node_modules/requirejs/bin/r.js -o optimize.js"
\r
625 grunt.initConfig( grunt.util._.extend( taskConfig, userConfig, envConfig ) );
\r
628 * In order to make it safe to just compile or copy *only* what was changed,
\r
629 * we need to ensure we are starting from a clean, fresh build. So we rename
\r
630 * the `watch` task to `delta` (that's why the configuration var above is
\r
631 * `delta`) and then add a new task called `watch` that does a clean build
\r
632 * before watching for changes.
\r
634 grunt.renameTask( 'watch', 'delta' );
\r
635 grunt.registerTask( 'watch', [ 'build', 'karma:unit', 'delta' ] );
\r
637 grunt.registerTask('live', ['build', 'connect:dev', 'delta']);
\r
639 * The default task is to build and compile.
\r
641 grunt.registerTask( 'default', [ 'compile' ] );
\r
644 * The `build` task gets your app ready to run for development and testing.
\r
646 grunt.registerTask( 'common', [
\r
647 'clean', 'html2js', 'jshint', 'concat:build_css', 'less:development',
\r
648 'copy:build_app_assets', 'copy:build_vendor_assets',
\r
649 'copy:build_appjs', 'copy:copy_template', 'copy:build_vendorimages', 'copy:build_appimages', 'copy:build_vendorjs', 'copy:build_vendorcss', 'karmaconfig', 'index:build'
\r
652 grunt.registerTask( 'build', ['replace:development', 'common', 'karma:continuous']);
\r
655 * The `compile` task gets your app ready for deployment by concatenating and
\r
656 * minifying your code.
\r
658 grunt.registerTask( 'compile', ['replace:production', 'common', 'karma:continuous', 'ngAnnotate', 'shell:requirejs']);
\r
661 * A utility function to get all app JavaScript sources.
\r
663 function filterForJS ( files ) {
\r
664 return files.filter( function ( file ) {
\r
665 return file.match( /\.js$/ );
\r
670 * A utility function to get all app CSS sources.
\r
672 function filterForCSS ( files ) {
\r
673 return files.filter( function ( file ) {
\r
674 return file.match( /\.css$/ );
\r
679 * The index.html template includes the stylesheet and javascript sources
\r
680 * based on dynamic names calculated in this Gruntfile. This task assembles
\r
681 * the list into variables for the template to use and then runs the
\r
684 grunt.registerMultiTask( 'index', 'Process index.html template', function () {
\r
685 var dirRE = new RegExp( '^('+grunt.config('build_dir')+'|'+grunt.config('compile_dir')+')\/', 'g' );
\r
686 var jsFiles = filterForJS( this.filesSrc ).map( function ( file ) {
\r
687 return file.replace( dirRE, '' );
\r
689 var cssFiles = filterForCSS( this.filesSrc ).map( function ( file ) {
\r
690 return file.replace( dirRE, '' );
\r
693 grunt.file.copy('src/index.html', this.data.dir + '/index.html', {
\r
694 process: function ( contents, path ) {
\r
695 return grunt.template.process( contents, {
\r
699 version: grunt.config( 'pkg.version' )
\r
707 * In order to avoid having to specify manually the files needed for karma to
\r
708 * run, we use grunt to manage the list for us. The `karma/*` files are
\r
709 * compiled as grunt templates for use by Karma. Yay!
\r
711 grunt.registerMultiTask( 'karmaconfig', 'Process karma config templates', function () {
\r
712 var jsFiles = filterForJS( this.filesSrc );
\r
714 grunt.file.copy( 'karma/karma-unit.tpl.js', grunt.config( 'build_dir' ) + '/karma-unit.js', {
\r
715 process: function ( contents, path ) {
\r
716 return grunt.template.process( contents, {
\r