Skip to content

Instantly share code, notes, and snippets.

@jbutko
Created February 15, 2015 21:27
Show Gist options
  • Save jbutko/f9ac4bca3b7e514bb1b4 to your computer and use it in GitHub Desktop.
Save jbutko/f9ac4bca3b7e514bb1b4 to your computer and use it in GitHub Desktop.
#AngularJS, #JS: #Gulp Build task of an ordinary AngularJS app
/**
* @author Jozef Butko
* @date Feb/2014
* @status Work in progress
*
* The following build process consists of these steps:
* 1. clean _build folder
* 2. compile SASS files, minify and uncss compiled css
* 3. copy and minimize images
* 4. build index.html and change base tag into _build folder
* 5. copy fonts
* 6. copy components folder - directives, services etc., only html
* 7. TODO: transform views into templateCache
*
*/
var browserSync = require('browser-sync');
var reload = browserSync.reload;
var gulp = require('gulp');
var sass = require('gulp-sass');
var filter = require('gulp-filter');
var uglify = require('gulp-uglify');
var minifyCSS = require('gulp-minify-css');
var minifyHTML = require('gulp-minify-html');
var del = require('del'); // delete files
var concat = require('gulp-concat');
var gulp = require('gulp');
var imagemin = require('gulp-imagemin');
var sass = require('gulp-sass');
var sourcemaps = require('gulp-sourcemaps');
var autoprefixer = require('gulp-autoprefixer');
var rename = require('gulp-rename');
var notify = require('gulp-notify');
var changed = require('gulp-changed');
var usemin = require('gulp-usemin');
var rev = require('gulp-rev');// append revision numbers at the end of filename: https://github.com/sindresorhus/gulp-rev
var size = require('gulp-size');
var inject = require('gulp-inject');
var angularFilesort = require('gulp-angular-filesort');
var uncss = require('gulp-uncss');
// var csso = require('gulp-csso');
var htmlreplace = require('gulp-html-replace');
var $ = require('gulp-load-plugins')(); // TODO
// process.setMaxListeners(0);
// optimize images
gulp.task('images', function () {
return gulp.src('./images/*')
// .pipe(imagemin({
// progressive: true,
// svgoPlugins: [{removeViewBox: false}],
// use: [pngquant()]
// }))
.pipe(changed('./_build/images'))
.pipe(imagemin({
optimizationLevel: 3,
progressive: true,
interlaced: true
}))
.pipe(gulp.dest('./_build/images'));
});
// Browser-sync task, only cares about compiled CSS
gulp.task('browser-sync', function() {
browserSync({
server: {
baseDir: "./"
}
});
});
// minify JS
gulp.task('minify-js', function() {
gulp.src('js/*.js')
.pipe(uglify())
.pipe(gulp.dest('./_build/'));
});
// minify CSS
gulp.task('minify-css', function() {
gulp.src(['./css/**/*.css', '!./css/**/*.min.css'])
.pipe(rename({suffix: '.min'}))
.pipe(minifyCSS({keepBreaks:true}))
.pipe(gulp.dest('./css/'))
.pipe(gulp.dest('./_build/css/'));
});
// minify HTML
gulp.task('minify-html', function() {
var opts = {
comments: true,
spare:true,
conditionals: true
};
gulp.src('./*.html')
.pipe(minifyHTML(opts))
.pipe(gulp.dest('./_build/'));
});
// Copy fonts from a module outside of our project (like Bower)
gulp.task('fonts', function() {
gulp.src('./fonts/**/*.{ttf,woff,eof,eot,svg}')
.pipe(changed('./_build/fonts'))
.pipe(gulp.dest('./_build/fonts'));
});
// copy components html
gulp.task('components', function() {
gulp.src('./components/**/*.html')
.pipe(changed('./_build/components'))
.pipe(gulp.dest('./_build/components'));
});
// copy views html
gulp.task('views', function() {
gulp.src('./views/**/*.html')
.pipe(changed('./_build/views'))
.pipe(gulp.dest('./_build/views'));
});
// delete build folder
gulp.task('clean:build', function (cb) {
del([
// here we use a globbing pattern to match everything inside the `build` folder
'./_build/*.*',
'./_build/css/**/*.*',
'./_build/js/**/*.*',
// we don't want to clean this file though so we negate the pattern
//'!dist/mobile/deploy.json'
], cb);
});
// concat files
gulp.task('concat', function() {
gulp.src('./js/*.js')
.pipe(concat('scripts.js'))
.pipe(gulp.dest('./_build/'));
});
// Sass task, will run when any SCSS files change & BrowserSync
// will auto-update browsers
gulp.task('sass', function () {
return gulp.src('styles/**/*.scss')
.pipe(sourcemaps.init())
.pipe(sass({ style: 'expanded' }))
.on('error', notify.onError({
title: 'SASS Failed',
message: 'Error(s) occurred during compile!'
}))
.pipe(autoprefixer('last 3 version'))
.pipe(sourcemaps.write())
.pipe(gulp.dest('css'))
.pipe(reload({stream: true}))
.pipe(notify({ message: 'Styles task complete' }));
});
gulp.task('sass:build', function() {
var s = size();
return gulp.src('styles/**/*.scss')
.pipe(sass({
style: 'compact'
}))
.pipe(autoprefixer('last 3 version'))
// .pipe(uncss({
// html: ['./index.html', './views/**/*.html', './components/**/*.html']
// }))
.pipe(minifyCSS({
keepBreaks: true,
aggressiveMerging: false,
advanced: false
}))
.pipe(gulp.dest('css'))
.pipe(s)
.pipe(notify({
onLast: true,
message: function() {
return 'Total CSS size ' + s.prettySize;
}
}));
});
// BUGFIX: warning: possible EventEmitter memory leak detected. 11 listeners added.
require('events').EventEmitter.prototype._maxListeners = 100;
// index.html build
// script/css concatenation
gulp.task('usemin', function () {
return gulp.src('./index.html')
// base path replace
.pipe(htmlreplace({
'base': '<base href="/_build/">'
}))
.pipe(usemin({
css: [ minifyCSS(), 'concat' ],
//html: [minifyHTML({empty: true})],
js: [ uglify(), rev() ]
}))
.pipe(gulp.dest('./_build/'));
});
// Reload all Browsers
gulp.task('bs-reload', function () {
browserSync.reload();
});
// Default task to be run with `gulp`
// This default task will run BrowserSync & then use Gulp to watch files.
// When a file is changed, an event is emitted to BrowserSync with the filepath.
gulp.task('default', ['browser-sync', 'sass', 'minify-css'], function () {
gulp.watch('css/*.css', function (file) {
if (file.type === "changed") {
reload(file.path);
}
});
gulp.watch('*.html', ['bs-reload']);
gulp.watch('views/*.html', ['bs-reload']);
gulp.watch('app/*.js', ['bs-reload']);
gulp.watch('js/*.js', ['bs-reload']);
gulp.watch('components/**/*.js', ['bs-reload']);
gulp.watch('styles/**/*.scss', ['sass', 'minify-css']);
});
/**
* Build Task:
* 1. clean _build folder
* 2. compile SASS files, minify and uncss compiled css
* 3. copy and minimize images
* 4. build index.html and change base tag into _build folder
* 5. copy fonts
* 6. copy components folder - directives, services etc., only html
* 7. copy views TODO: templateCache
*/
gulp.task('build', ['clean:build', 'sass:build', 'images', 'usemin', 'fonts', 'components', 'views'],
function() {
var s = size();
return gulp.src('./_build/**/*.*')
.pipe(s)
.pipe(notify({
onLast: true,
message: function() {
return 'Total size ' + s.prettySize;
}
}));
});
<!doctype html>
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html lang="en" ng-csp="" ng-app="theApp"> <!--<![endif]-->
<head>
<!-- build:base -->
<base href="/">
<!-- endbuild -->
<meta charset="utf-8">
<title>The Portfolio of designer</title>
<meta name="description" content="">
<!-- mobile meta (hooray!) -->
<meta name="HandheldFriendly" content="True">
<meta name="MobileOptimized" content="320">
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<!-- icons & favicons (for more: http://www.jonathantneal.com/blog/understand-the-favicon/) -->
<!-- <link rel="shortcut icon" href="/twentytwelve/library/images/tin-favicon.png"> -->
<link rel="shortcut icon" href="images/favicon.ico">
<!--[if IE]>
<link rel="shortcut icon" href="/twentytwelve/favicon.ico">
<![endif]-->
<!-- or, set /favicon.ico for IE10 win -->
<meta name="msapplication-TileColor" content="#f01d4f">
<!-- fire up adaptive-images script, more info: adaptive-images.com -->
<script>document.cookie='resolution='+Math.max(screen.width,screen.height)+'; path=/';</script>
<!--[if lt IE 9]>
<link rel='stylesheet' id='bones-ie-only-css' href='/twentytwelve/library/css/ie.css' type='text/css' media='all' />
<![endif]-->
<!-- Slider CSS -->
<!-- build:css css/vendor/vendor.css -->
<link rel='stylesheet' id='metaslider-responsive-slider-css' href='css/vendor/responsiveslides.css' type='text/css' media='all' />
<link rel='stylesheet' id='metaslider-public-css' href='css/vendor/metaslider-public.css' type='text/css' media='all' />
<link rel='stylesheet' id='googleFonts-css' href='css/vendor/lato-font.css' type='text/css' media='all' />
<link rel="stylesheet" href="bower_components/owl.carousel/dist/assets/owl.carousel.min.css" />
<!-- endbuild -->
<!-- build:cssApp css/app.min.css -->
<link rel="stylesheet" type="text/css" href="css/app.css" />
<!-- endbuild -->
</head>
<body class="main-wrapper">
<!-- Navigation -->
<tin-main-nav></tin-main-nav>
<!-- MAIN CONTAINER FOR ANGULAR TEMPLATES -->
<div data-ng-view="" class="container-fluid"></div>
</body>
<!-- Vendors -->
<!-- build:nonangularlibs js/nonangularlibs.js -->
<script src="js/nonangular/jquery-1.11.2.min.js"></script>
<script type="text/javascript" src="js/nonangular/responsiveslides.min.js"></script>
<!-- endbuild -->
<!-- build:libs js/libs.js -->
<script type="text/javascript" src="js/nonangular/lodash.min.js"></script>
<script type="text/javascript" src="bower_components/jquery-bridget/jquery.bridget.js"></script>
<script type="text/javascript" src="bower_components/get-style-property/get-style-property.js"></script>
<script type="text/javascript" src="bower_components/get-size/get-size.js"></script>
<script type="text/javascript" src="bower_components/eventEmitter/EventEmitter.js"></script>
<script type="text/javascript" src="bower_components/eventie/eventie.js"></script>
<script type="text/javascript" src="bower_components/doc-ready/doc-ready.js"></script>
<script type="text/javascript" src="bower_components/matches-selector/matches-selector.js"></script>
<script type="text/javascript" src="bower_components/outlayer/item.js"></script>
<script type="text/javascript" src="bower_components/outlayer/outlayer.js"></script>
<script type="text/javascript" src="bower_components/masonry/masonry.js"></script>
<script type="text/javascript" src="bower_components/imagesloaded/imagesloaded.js"></script>
<script type="text/javascript" src="js/scripts.js"></script>
<script type="text/javascript" src="bower_components/owl.carousel/dist/owl.carousel.min.js"></script>
<!-- endbuild -->
<!-- Angular external libraries for application -->
<!-- build:angularlibs js/angularlibs.js -->
<script type="text/javascript" src="bower_components/angular/angular.js"></script>
<script type="text/javascript" src="bower_components/angular-route/angular-route.js"></script>
<script type="text/javascript" src="bower_components/angular-sanitize/angular-sanitize.js"></script>
<script type="text/javascript" src="bower_components/angular-masonry/angular-masonry.js"></script>
<script type="text/javascript" src="bower_components/angular-masonry-directive/src/angular-masonry-directive.js"></script>
<!-- endbuild -->
<!-- Section for library javascript files, that can be used within the application -->
<!-- Angular components -->
<!-- build:appcomponents js/appcomponents.js -->
<script type="text/javascript" src="app/app.js"></script>
<script type="text/javascript" src="app/config.js"></script>
<script type="text/javascript" src="components/services/LocalStorage.service.js"></script>
<script type="text/javascript" src="components/services/queryService.service.js"></script>
<script type="text/javascript" src="components/directives/main.nav.directive.js"></script>
<script type="text/javascript" src="components/directives/responsive.nav.directive.js"></script>
<script type="text/javascript" src="components/directives/hover.center.directive.js"></script>
<script type="text/javascript" src="components/directives/angular.centered.directive.js"></script>
<script type="text/javascript" src="components/directives/slider.directive.js"></script>
<script type="text/javascript" src="components/directives/owl.slider.directive.js"></script>
<script type="text/javascript" src="components/directives/dot.hover.directive.js"></script>
<!-- endbuild -->
<!-- Application sections -->
<!-- build:mainapp js/mainapp.js -->
<script type="text/javascript" src="app/factory.js"></script>
<script type="text/javascript" src="app/controller.js"></script>
<!-- endbuild -->
</html>
{
"name": "getPocketExtended",
"version": "1.0.0",
"license": "MIT",
"dependencies": {
"jpegtran-bin": "0.2.0",
"gulp-rename": "^1.2.0",
"del": "^1.1.1",
"gulp-concat": "^2.4.3",
"gulp-ruby-sass": "^1.0.0-alpha.2",
"gulp-minify-css": "^0.4.2",
"gulp-uglify": "^1.1.0",
"gulp-livereload": "^3.5.0",
"gulp-jshint": "^1.9.0",
"gulp-notify": "^2.1.0",
"gulp-cache": "^0.2.4",
"gulp-autoprefixer": "^2.1.0",
"gulp-imagemin": "^2.1.0",
"gulp": "^3.8.10",
"gulp-uncss": "^1.0.0",
"connect": "^3.3.1",
"connect-livereload": "^0.5.0",
"opn": "^1.0.0",
"serve-index": "^1.5.0",
"serve-static": "^1.7.1",
"tiny-lr": "^0.1.4",
"watch": "^0.13.0",
"browser-sync": "^1.9.1",
"gulp-filter": "^2.0.0",
"gulp-sass": "^1.3.2",
"gulp-minify-html": "^0.1.8",
"gulp-sourcemaps": "^1.3.0"
},
"devDependencies": {
"gulp-angular-filesort": "^1.0.4",
"gulp-autoprefixer": "^2.1.0",
"gulp-changed": "^1.1.1",
"gulp-csso": "^1.0.0",
"gulp-html-replace": "^1.4.4",
"gulp-inject": "^1.1.1",
"gulp-load-plugins": "^0.8.0",
"gulp-notify": "^2.2.0",
"gulp-rename": "^1.2.0",
"gulp-rev": "^3.0.1",
"gulp-size": "^1.2.0",
"gulp-usemin": "^0.3.11"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment