Tutorial: Foundation for Apps Setup With AngularJS Best Practices – Part 2
This part of the tutorial assumes that you have already followed the previous steps of the tutorial. The first part of the tutorial will walk you through setting up all the prerequisites and dependencies. If you have not gone through these yet, please visit the first part of the tutorial: Foundation for Apps Setup with AngularJS Best Practices.
Build Script
Now that we have everything installed, we can create our build script. By creating it now, we can speed up development and quickly see changes that we make as we go. All the required dependencies were installed when we used npm.
Setup Libraries
For our build tasks we will be using gulp. Gulp reads in a file named gulpfile.js at the root directory of our project for configuration of requirements and tasks. So to get started we need to tell gulp what libraries we intend to use:
// FOUNDATION FOR APPS TEMPLATE GULPFILE // ------------------------------------- // This file processes all of the assets in the "src/app" folder, combines them with the Foundation // for Apps assets, and outputs the finished files in the "dist" folder as a finished app. // 1. LIBRARIES // - - - - - - - - - - - - - - - var gulp = require('gulp'), $ = require('gulp-load-plugins')(), rimraf = require('rimraf'), sequence = require('run-sequence'), path = require('path'), modRewrite = require('connect-modrewrite') //router = require('./src/app/bower_components/foundation-apps/bin/gulp-dynamic-routing');
Setup Variables
Next we will create some settings variables to use throughout the rest of the script. Here we are just defining variables for the different directories and files.
// FOUNDATION FOR APPS TEMPLATE GULPFILE // ------------------------------------- // This file processes all of the assets in the "src/app" folder, combines them with the Foundation // for Apps assets, and outputs the finished files in the "dist" folder as a finished app. // 1. LIBRARIES // - - - - - - - - - - - - - - - var gulp = require('gulp'), $ = require('gulp-load-plugins')(), rimraf = require('rimraf'), sequence = require('run-sequence'), path = require('path'), modRewrite = require('connect-modrewrite') //router = require('./src/app/bower_components/foundation-apps/bin/gulp-dynamic-routing'); // 2. SETTINGS VARIABLES // - - - - - - - - - - - - - - - // Sass will check these folders for files when you use @import. var sassPaths = [ 'src/app/scss', 'src/app/bower_components/foundation-apps/scss' ]; // These files include Foundation for Apps and its dependencies var foundationJS = [ 'src/app/bower_components/fastclick/lib/fastclick.js', 'src/app/bower_components/viewport-units-buggyfill/viewport-units-buggyfill.js', 'src/app/bower_components/tether/tether.js', 'src/app/bower_components/angular/angular.js', 'src/app/bower_components/angular-animate/angular-animate.js', 'src/app/bower_components/angular-ui-router/release/angular-ui-router.js', 'src/app/bower_components/foundation-apps/js/vendor/**/*.js', 'src/app/bower_components/foundation-apps/js/angular/**/*.js', '!src/app/bower_components/foundation-apps/js/angular/app.js' ]; // These files are for your app's JavaScript var appJS = [ 'src/app/**/*.js', '!src/app/bower_components/**/*.js' ];
Setup Tasks
Now we will begin writing out our tasks. These are what tells gulp what to do for the different phases and parts of the build process.
Clean Task
The “clean” task will be used to remove the files that were built for deployment. We will want to “clean” the project when we want the app to be completely rebuilt.
// FOUNDATION FOR APPS TEMPLATE GULPFILE // ------------------------------------- // This file processes all of the assets in the "src/app" folder, combines them with the Foundation // for Apps assets, and outputs the finished files in the "dist" folder as a finished app. // 1. LIBRARIES // - - - - - - - - - - - - - - - var gulp = require('gulp'), $ = require('gulp-load-plugins')(), rimraf = require('rimraf'), sequence = require('run-sequence'), path = require('path'), modRewrite = require('connect-modrewrite') //router = require('./src/app/bower_components/foundation-apps/bin/gulp-dynamic-routing'); // 2. SETTINGS VARIABLES // - - - - - - - - - - - - - - - // Sass will check these folders for files when you use @import. var sassPaths = [ 'src/app/scss', 'src/app/bower_components/foundation-apps/scss' ]; // These files include Foundation for Apps and its dependencies var foundationJS = [ 'src/app/bower_components/fastclick/lib/fastclick.js', 'src/app/bower_components/viewport-units-buggyfill/viewport-units-buggyfill.js', 'src/app/bower_components/tether/tether.js', 'src/app/bower_components/angular/angular.js', 'src/app/bower_components/angular-animate/angular-animate.js', 'src/app/bower_components/angular-ui-router/release/angular-ui-router.js', 'src/app/bower_components/foundation-apps/js/vendor/**/*.js', 'src/app/bower_components/foundation-apps/js/angular/**/*.js', '!src/app/bower_components/foundation-apps/js/angular/app.js' ]; // These files are for your app's JavaScript var appJS = [ 'src/app/**/*.js', '!src/app/bower_components/**/*.js' ]; // 3. TASKS // - - - - - - - - - - - - - - - // Cleans the build directory gulp.task('clean', function(cb) { rimraf('./dist', cb); });
Copy Task
This task will tell gulp what files to copy directly over to the “dist” folder. First we list out the file paths that we want to copy. We then tell it to use the “dist” folder for the copy location. We do this for user-created files and Foundation assets such as the svg icons and the foundation AngularJS pieces.
// FOUNDATION FOR APPS TEMPLATE GULPFILE // ------------------------------------- // This file processes all of the assets in the "src/app" folder, combines them with the Foundation // for Apps assets, and outputs the finished files in the "dist" folder as a finished app. // 1. LIBRARIES // - - - - - - - - - - - - - - - var gulp = require('gulp'), $ = require('gulp-load-plugins')(), rimraf = require('rimraf'), sequence = require('run-sequence'), path = require('path'), modRewrite = require('connect-modrewrite') //router = require('./src/app/bower_components/foundation-apps/bin/gulp-dynamic-routing'); // 2. SETTINGS VARIABLES // - - - - - - - - - - - - - - - // Sass will check these folders for files when you use @import. var sassPaths = [ 'src/app/scss', 'src/app/bower_components/foundation-apps/scss' ]; // These files include Foundation for Apps and its dependencies var foundationJS = [ 'src/app/bower_components/fastclick/lib/fastclick.js', 'src/app/bower_components/viewport-units-buggyfill/viewport-units-buggyfill.js', 'src/app/bower_components/tether/tether.js', 'src/app/bower_components/angular/angular.js', 'src/app/bower_components/angular-animate/angular-animate.js', 'src/app/bower_components/angular-ui-router/release/angular-ui-router.js', 'src/app/bower_components/foundation-apps/js/vendor/**/*.js', 'src/app/bower_components/foundation-apps/js/angular/**/*.js', '!src/app/bower_components/foundation-apps/js/angular/app.js' ]; // These files are for your app's JavaScript var appJS = [ 'src/app/**/*.js', '!src/app/bower_components/**/*.js' ]; // 3. TASKS // - - - - - - - - - - - - - - - // Cleans the build directory gulp.task('clean', function(cb) { rimraf('./dist', cb); }); // Copies user-created files and Foundation assets gulp.task('copy', function() { var dirs = [ './src/app/**/*.*', '!./src/app/bower_components/**/*.*', '!./src/app/scss/**/*.*' ]; // Everything in the client folder except templates, Sass, and JS gulp.src(dirs, { base: './src/app/' }) .pipe(gulp.dest('./dist')); // Iconic SVG icons gulp.src('./src/app/bower_components/foundation-apps/iconic/**/*') .pipe(gulp.dest('./dist/img/iconic/')); // Foundation's Angular partials return gulp.src(['.src/app/bower_components/foundation-apps/js/angular/components/**/*.html']) .pipe(gulp.dest('./dist/components/lib')); });
Sass Tasks
Next we will tell gulp how we want to process our sass files. We use the “sassPaths” variable that was created earlier for the option to tell the sass processor when to find include files . We also have to give the location of our sass files and where to put the processed output. In our case it will be the “dist” directory.
// FOUNDATION FOR APPS TEMPLATE GULPFILE // ------------------------------------- // This file processes all of the assets in the "src/app" folder, combines them with the Foundation // for Apps assets, and outputs the finished files in the "dist" folder as a finished app. // 1. LIBRARIES // - - - - - - - - - - - - - - - var gulp = require('gulp'), $ = require('gulp-load-plugins')(), rimraf = require('rimraf'), sequence = require('run-sequence'), path = require('path'), modRewrite = require('connect-modrewrite') //router = require('./src/app/bower_components/foundation-apps/bin/gulp-dynamic-routing'); // 2. SETTINGS VARIABLES // - - - - - - - - - - - - - - - // Sass will check these folders for files when you use @import. var sassPaths = [ 'src/app/scss', 'src/app/bower_components/foundation-apps/scss' ]; // These files include Foundation for Apps and its dependencies var foundationJS = [ 'src/app/bower_components/fastclick/lib/fastclick.js', 'src/app/bower_components/viewport-units-buggyfill/viewport-units-buggyfill.js', 'src/app/bower_components/tether/tether.js', 'src/app/bower_components/angular/angular.js', 'src/app/bower_components/angular-animate/angular-animate.js', 'src/app/bower_components/angular-ui-router/release/angular-ui-router.js', 'src/app/bower_components/foundation-apps/js/vendor/**/*.js', 'src/app/bower_components/foundation-apps/js/angular/**/*.js', '!src/app/bower_components/foundation-apps/js/angular/app.js' ]; // These files are for your app's JavaScript var appJS = [ 'src/app/**/*.js', '!src/app/bower_components/**/*.js' ]; // 3. TASKS // - - - - - - - - - - - - - - - // Cleans the build directory gulp.task('clean', function(cb) { rimraf('./dist', cb); }); // Copies user-created files and Foundation assets gulp.task('copy', function() { var dirs = [ './src/app/**/*.*', '!./src/app/bower_components/**/*.*', '!./src/app/scss/**/*.*' ]; // Everything in the client folder except templates, Sass, and JS gulp.src(dirs, { base: './src/app/' }) .pipe(gulp.dest('./dist')); // Iconic SVG icons gulp.src('./src/app/bower_components/foundation-apps/iconic/**/*') .pipe(gulp.dest('./dist/img/iconic/')); // Foundation's Angular partials return gulp.src(['.src/app/bower_components/foundation-apps/js/angular/components/**/*.html']) .pipe(gulp.dest('./dist/components/lib')); }); // Compiles Sass gulp.task('sass', function() { return gulp.src('src/app/scss/app.scss') .pipe($.sass({ includePaths: sassPaths, sourcemap: true })).on('error', function(e) { console.log(e); }) .pipe($.autoprefixer({ browsers: ['last 2 versions', 'ie 10'] })) .pipe(gulp.dest('./dist/css/')); });
Uglify (js compile)Â Task
We also need to tell gulp to compile our JavaScript files. By using the foundationJS variable we  created earlier, we tell gulp what files we want to compile and give it the options we want. We then tell it to concatenate all the files into one file, foundation.js. After that we do the same for the JavaScript we will create for our web app.
// FOUNDATION FOR APPS TEMPLATE GULPFILE // ------------------------------------- // This file processes all of the assets in the "src/app" folder, combines them with the Foundation // for Apps assets, and outputs the finished files in the "dist" folder as a finished app. // 1. LIBRARIES // - - - - - - - - - - - - - - - var gulp = require('gulp'), $ = require('gulp-load-plugins')(), rimraf = require('rimraf'), sequence = require('run-sequence'), path = require('path'), modRewrite = require('connect-modrewrite') //router = require('./src/app/bower_components/foundation-apps/bin/gulp-dynamic-routing'); // 2. SETTINGS VARIABLES // - - - - - - - - - - - - - - - // Sass will check these folders for files when you use @import. var sassPaths = [ 'src/app/scss', 'src/app/bower_components/foundation-apps/scss' ]; // These files include Foundation for Apps and its dependencies var foundationJS = [ 'src/app/bower_components/fastclick/lib/fastclick.js', 'src/app/bower_components/viewport-units-buggyfill/viewport-units-buggyfill.js', 'src/app/bower_components/tether/tether.js', 'src/app/bower_components/angular/angular.js', 'src/app/bower_components/angular-animate/angular-animate.js', 'src/app/bower_components/angular-ui-router/release/angular-ui-router.js', 'src/app/bower_components/foundation-apps/js/vendor/**/*.js', 'src/app/bower_components/foundation-apps/js/angular/**/*.js', '!src/app/bower_components/foundation-apps/js/angular/app.js' ]; // These files are for your app's JavaScript var appJS = [ 'src/app/**/*.js', '!src/app/bower_components/**/*.js' ]; // 3. TASKS // - - - - - - - - - - - - - - - // Cleans the build directory gulp.task('clean', function(cb) { rimraf('./dist', cb); }); // Copies user-created files and Foundation assets gulp.task('copy', function() { var dirs = [ './src/app/**/*.*', '!./src/app/bower_components/**/*.*', '!./src/app/scss/**/*.*' ]; // Everything in the client folder except templates, Sass, and JS gulp.src(dirs, { base: './src/app/' }) .pipe(gulp.dest('./dist')); // Iconic SVG icons gulp.src('./src/app/bower_components/foundation-apps/iconic/**/*') .pipe(gulp.dest('./dist/img/iconic/')); // Foundation's Angular partials return gulp.src(['.src/app/bower_components/foundation-apps/js/angular/components/**/*.html']) .pipe(gulp.dest('./dist/components/lib')); }); // Compiles Sass gulp.task('sass', function() { return gulp.src('src/app/scss/app.scss') .pipe($.sass({ includePaths: sassPaths, sourcemap: true })).on('error', function(e) { console.log(e); }) .pipe($.autoprefixer({ browsers: ['last 2 versions', 'ie 10'] })) .pipe(gulp.dest('./dist/css/')); }); // Compiles and copies the Foundation for Apps JavaScript, as well as your app's custom JS gulp.task('uglify', function() { // Foundation JavaScript gulp.src(foundationJS) .pipe($.uglify({ beautify: true, mangle: false }).on('error', function(e) { console.log(e); })) .pipe($.concat('foundation.js')) .pipe(gulp.dest('./dist/components/lib/')) ; // App JavaScript return gulp.src(appJS) .pipe($.uglify({ beautify: true, mangle: false }).on('error', function(e) { console.log(e); })) .pipe($.concat('app.js')) .pipe(gulp.dest('./dist/')) ; });
Server Task
This is an optional task. You can set up your own web server if you want. This task is included if you want your developers to use node’s web server. As you can see in the code, we need to tell the http-server where the root directory that will be used to serve up the files will be. Then we need to configure modRewrite to route all requests through the index.html file. The index.html will be the file that bootstraps the web app and will also handling the routing duties.
// FOUNDATION FOR APPS TEMPLATE GULPFILE // ------------------------------------- // This file processes all of the assets in the "src/app" folder, combines them with the Foundation // for Apps assets, and outputs the finished files in the "dist" folder as a finished app. // 1. LIBRARIES // - - - - - - - - - - - - - - - var gulp = require('gulp'), $ = require('gulp-load-plugins')(), rimraf = require('rimraf'), sequence = require('run-sequence'), path = require('path'), modRewrite = require('connect-modrewrite') //router = require('./src/app/bower_components/foundation-apps/bin/gulp-dynamic-routing'); // 2. SETTINGS VARIABLES // - - - - - - - - - - - - - - - // Sass will check these folders for files when you use @import. var sassPaths = [ 'src/app/scss', 'src/app/bower_components/foundation-apps/scss' ]; // These files include Foundation for Apps and its dependencies var foundationJS = [ 'src/app/bower_components/fastclick/lib/fastclick.js', 'src/app/bower_components/viewport-units-buggyfill/viewport-units-buggyfill.js', 'src/app/bower_components/tether/tether.js', 'src/app/bower_components/angular/angular.js', 'src/app/bower_components/angular-animate/angular-animate.js', 'src/app/bower_components/angular-ui-router/release/angular-ui-router.js', 'src/app/bower_components/foundation-apps/js/vendor/**/*.js', 'src/app/bower_components/foundation-apps/js/angular/**/*.js', '!src/app/bower_components/foundation-apps/js/angular/app.js' ]; // These files are for your app's JavaScript var appJS = [ 'src/app/**/*.js', '!src/app/bower_components/**/*.js' ]; // 3. TASKS // - - - - - - - - - - - - - - - // Cleans the build directory gulp.task('clean', function(cb) { rimraf('./dist', cb); }); // Copies user-created files and Foundation assets gulp.task('copy', function() { var dirs = [ './src/app/**/*.*', '!./src/app/bower_components/**/*.*', '!./src/app/scss/**/*.*' ]; // Everything in the client folder except templates, Sass, and JS gulp.src(dirs, { base: './src/app/' }) .pipe(gulp.dest('./dist')); // Iconic SVG icons gulp.src('./src/app/bower_components/foundation-apps/iconic/**/*') .pipe(gulp.dest('./dist/img/iconic/')); // Foundation's Angular partials return gulp.src(['.src/app/bower_components/foundation-apps/js/angular/components/**/*.html']) .pipe(gulp.dest('./dist/components/lib')); }); // Compiles Sass gulp.task('sass', function() { return gulp.src('src/app/scss/app.scss') .pipe($.sass({ includePaths: sassPaths, sourcemap: true })).on('error', function(e) { console.log(e); }) .pipe($.autoprefixer({ browsers: ['last 2 versions', 'ie 10'] })) .pipe(gulp.dest('./dist/css/')); }); // Compiles and copies the Foundation for Apps JavaScript, as well as your app's custom JS gulp.task('uglify', function() { // Foundation JavaScript gulp.src(foundationJS) .pipe($.uglify({ beautify: true, mangle: false }).on('error', function(e) { console.log(e); })) .pipe($.concat('foundation.js')) .pipe(gulp.dest('./dist/components/lib/')) ; // App JavaScript return gulp.src(appJS) .pipe($.uglify({ beautify: true, mangle: false }).on('error', function(e) { console.log(e); })) .pipe($.concat('app.js')) .pipe(gulp.dest('./dist/')) ; }); // Starts a test server, which you can view at http://localhost:8080 gulp.task('server:start', function() { $.connect.server({ root: './dist', middleware: function() { return [ modRewrite(['^[^\\.]*$ /index.html [L]']) ]; }, }); });
Build and Default Tasks
The final tasks to set up are the tasks that tie everything together. We start with the “build” task. This task is used when we just want to build our web app without starting the web server. This task is just takes a series of tasks to run in a specific order and runs them.
We also define a “default” task. This is used when you run gulp without any arguments. This is what will be run when you just enter “gulp” at the command prompt. This also is just a series of tasks we already defined. You will notice though that we also define a few “gulp.watch” statements. This tells gulp to watch a set of files and perform a task or tasks if it notices any changes. This will set it up so that anytime we edit or create a file we don’t have to keep re-running gulp. We can simple type gulp and then our web app comes to life as we create and edit the files.
// FOUNDATION FOR APPS TEMPLATE GULPFILE // ------------------------------------- // This file processes all of the assets in the "src/app" folder, combines them with the Foundation // for Apps assets, and outputs the finished files in the "dist" folder as a finished app. // 1. LIBRARIES // - - - - - - - - - - - - - - - var gulp = require('gulp'), $ = require('gulp-load-plugins')(), rimraf = require('rimraf'), sequence = require('run-sequence'), path = require('path'), modRewrite = require('connect-modrewrite') //router = require('./src/app/bower_components/foundation-apps/bin/gulp-dynamic-routing'); // 2. SETTINGS VARIABLES // - - - - - - - - - - - - - - - // Sass will check these folders for files when you use @import. var sassPaths = [ 'src/app/scss', 'src/app/bower_components/foundation-apps/scss' ]; // These files include Foundation for Apps and its dependencies var foundationJS = [ 'src/app/bower_components/fastclick/lib/fastclick.js', 'src/app/bower_components/viewport-units-buggyfill/viewport-units-buggyfill.js', 'src/app/bower_components/tether/tether.js', 'src/app/bower_components/angular/angular.js', 'src/app/bower_components/angular-animate/angular-animate.js', 'src/app/bower_components/angular-ui-router/release/angular-ui-router.js', 'src/app/bower_components/foundation-apps/js/vendor/**/*.js', 'src/app/bower_components/foundation-apps/js/angular/**/*.js', '!src/app/bower_components/foundation-apps/js/angular/app.js' ]; // These files are for your app's JavaScript var appJS = [ 'src/app/**/*.js', '!src/app/bower_components/**/*.js' ]; // 3. TASKS // - - - - - - - - - - - - - - - // Cleans the build directory gulp.task('clean', function(cb) { rimraf('./dist', cb); }); // Copies user-created files and Foundation assets gulp.task('copy', function() { var dirs = [ './src/app/**/*.*', '!./src/app/bower_components/**/*.*', '!./src/app/scss/**/*.*' ]; // Everything in the client folder except templates, Sass, and JS gulp.src(dirs, { base: './src/app/' }) .pipe(gulp.dest('./dist')); // Iconic SVG icons gulp.src('./src/app/bower_components/foundation-apps/iconic/**/*') .pipe(gulp.dest('./dist/img/iconic/')); // Foundation's Angular partials return gulp.src(['.src/app/bower_components/foundation-apps/js/angular/components/**/*.html']) .pipe(gulp.dest('./dist/components/lib')); }); // Compiles Sass gulp.task('sass', function() { return gulp.src('src/app/scss/app.scss') .pipe($.sass({ includePaths: sassPaths, sourcemap: true })).on('error', function(e) { console.log(e); }) .pipe($.autoprefixer({ browsers: ['last 2 versions', 'ie 10'] })) .pipe(gulp.dest('./dist/css/')); }); // Compiles and copies the Foundation for Apps JavaScript, as well as your app's custom JS gulp.task('uglify', function() { // Foundation JavaScript gulp.src(foundationJS) .pipe($.uglify({ beautify: true, mangle: false }).on('error', function(e) { console.log(e); })) .pipe($.concat('foundation.js')) .pipe(gulp.dest('./dist/components/lib/')) ; // App JavaScript return gulp.src(appJS) .pipe($.uglify({ beautify: true, mangle: false }).on('error', function(e) { console.log(e); })) .pipe($.concat('app.js')) .pipe(gulp.dest('./dist/')) ; }); // Starts a test server, which you can view at http://localhost:8080 gulp.task('server:start', function() { $.connect.server({ root: './dist', middleware: function() { return [ modRewrite(['^[^\\.]*$ /index.html [L]']) ]; }, }); }); // Builds your entire app once, without starting a server gulp.task('build', function() { sequence('clean', ['copy', 'sass', 'uglify'], function() { console.log("Successfully built."); }) }); // Default task: builds your app, starts a server, and recompiles assets when they change gulp.task('default', ['build', 'server:start'], function() { // Watch Sass gulp.watch(['./src/app/scss/**/*', './scss/**/*'], ['sass']); // Watch JavaScript gulp.watch(['./src/app/**/*.js', './js/**/*'], ['uglify']); // Watch static files gulp.watch(['./src/app/**/*.*', '!./src/app/bower_components/**/*.*', '!./src/app/scss/**/*.*'], ['copy']); });
That’s it for the build script. Now we are ready to move on to actually developing our web app. Continue to Part 3 of Foundation for Apps Setup With AngularJS Best Practices. Part 3 will take you through creating the web app.
Pingback: Tutorial: Foundation for Apps Setup With AngularJS Best Practices – Fedil's Blog
Pingback: Tutorial: Foundation for Apps Setup With AngularJS Best Practices – Part 3 – Fedil's Blog