On Github tmaximini / hybrid-mobile-app-meetup
module.exports = function(grunt) { grunt.initConfig({ concat: { options: { separator: ';' }, dist: { src: ['scripts/*.js'], dest: '<%= distFolder %>/main.js' }, deploy: { src:['deploy/*.js'], dest:'deploy.js' } }}); grunt.loadNpmTasks('grunt-contrib-concat'); grunt.registerTask('build', ['concat']); };
// general pattern gulp.task('scripts', function() { gulp.src('app/scripts/**/*.js') .pipe(anyGulpPlugin()) .pipe(gulp.dest('dist/scripts')) .on('error', errorHandlerFunc); });
'scripts/**/*.js'
'images/**/*.{jpg,png,gif}'
['app.js', '**/*.js', 'some/other/path/*.js']
// gulpfile.js var gulp = require('gulp'); // lots of plugins var concat = require('gulp-concat'); var uglify = require('gulp-uglify'); //... // or load all 'gulp-*' packages into plugins object var plugins = require('gulp-load-plugins')(); // any npm package var path = require('path'); // define tasks // example: copy images gulp.task('images', function() { return gulp.src('app/images/**/*.*') .pipe(gulp.dest(path.join('dist', 'images'))) }); // ... call this task via 'gulp images'basic gulpfile.js example
gulp.task('scripts', function() { gulp.src(['app.js', '**/*.js'], { cwd: 'app/scripts' }) .pipe(plugins.if(!build, plugins.changed(dest))) .pipe(plugins.if(build, plugins.ngAnnotate())) .pipe(plugins.if(stripDebug, plugins.stripDebug())) .pipe(plugins.if(build, plugins.concat('app.js'))) .pipe(plugins.if(build, plugins.uglify())) .pipe(plugins.if(build && !emulate, plugins.rev())) .pipe(gulp.dest(dest)) .on('error', errorHandler); });advanced example, gulp-if
// precompile .scss and concat with ionic.css gulp.task('styles', function() { var options = build ? { style: 'compressed' } : { style: 'expanded' }; var sassStream = plugins.rubySass('app/styles/main.scss', options) .pipe(plugins.autoprefixer('last 2 version')); var cssStream = gulp .src('bower_components/ionic/css/ionic.min.css'); return streamqueue({ objectMode: true }, cssStream, sassStream) .pipe(plugins.concat('main.css')) .pipe(plugins.if(build, plugins.stripCssComments())) .pipe(plugins.if(build && !emulate, plugins.rev())) .pipe(gulp.dest(path.join(targetDir, 'styles'))) .on('error', errorHandler); });advanced example, streams can be merged
// inject the files in index.html gulp.task('index', ['jsHint', 'scripts'], function() { // build has a '-versionnumber' suffix var cssNaming = 'styles/main*'; // injects 'src' into index.html at position 'tag' var _inject = function(src, tag) { return plugins.inject(src, { starttag: '', read: false, addRootSlash: false }); }; // get all our javascript sources // in development mode, it's better to add each file seperately. // it makes debugging easier. var _getAllScriptSources = function() { var scriptStream = gulp.src(['scripts/app.js', 'scripts/**/*.js'], { cwd: targetDir }); return streamqueue({ objectMode: true }, scriptStream); }; return gulp.src('app/index.html') // inject css .pipe(_inject(gulp.src(cssNaming, { cwd: targetDir }), 'app-styles')) // inject vendor.js .pipe(_inject(gulp.src('vendor*.js', { cwd: targetDir }), 'vendor')) // inject app.js (build) or all js files indivually (dev) .pipe(plugins.if(build, _inject(gulp.src('scripts/app*.js', { cwd: targetDir }), 'app'), _inject(_getAllScriptSources(), 'app') )) .pipe(gulp.dest(targetDir)) .on('error', errorHandler); });
Slides: thomasmaximini.com/hybrid-mobile-app-meetup/
Seed Project: github.com/tmaximini/ionic-gulp-seed
Yeoman Generator: github.com/tmaximini/generator-ionic-gulp
Blog Post: thomasmaximini.com/2015/02/10/speeding-up-ionic-app-development-with-gulp.html
Twitter: @tmaximini