MandalaTV
Personal and Professional Blog of Rich Hauck

Integrating gulp-file-include into Yeoman’s generator-gulp-webapp

by: Rich Hauck

Using include files in my HTML templates has become an essential part of my web design workflow, and I’ve been using gulp-file-include in conjunction with generator-gulp-webapp. While gulp-webapp includes a gulpfile.babel.js file, it needs a few modifications to get HTML include files to display both when serving and when building.

I came across a helpful thread here on GitHub, though as I stated in the comments, I couldn’t get includes to display when building. Below is the complete solution. Basically,

  1. I create a fileinclude task (L44)
  2. I modify the html task to include a fileInclude() call (L57)
  3. I include fileinclude in the serve task (L95)
  4. I check for include file changes within the watch task (L114)

Here’s the full file:

// generated on 2016-01-02 using generator-gulp-webapp 1.0.4
import gulp from 'gulp';
import gulpLoadPlugins from 'gulp-load-plugins';
import browserSync from 'browser-sync';
import del from 'del';
import {stream as wiredep} from 'wiredep';

const $ = gulpLoadPlugins();
const reload = browserSync.reload;

gulp.task('styles', () => {
  return gulp.src('app/styles/*.scss')
    .pipe($.plumber())
    .pipe($.sourcemaps.init())
    .pipe($.sass.sync({
      outputStyle: 'expanded',
      precision: 10,
      includePaths: ['.']
    }).on('error', $.sass.logError))
    .pipe($.autoprefixer({browsers: ['> 1%', 'last 2 versions', 'Firefox ESR']}))
    .pipe($.sourcemaps.write())
    .pipe(gulp.dest('.tmp/styles'))
    .pipe(reload({stream: true}));
});

function lint(files, options) {
  return () => {
    return gulp.src(files)
      .pipe(reload({stream: true, once: true}))
      .pipe($.eslint(options))
      .pipe($.eslint.format())
      .pipe($.if(!browserSync.active, $.eslint.failAfterError()));
  };
}
const testLintOptions = {
  env: {
    mocha: true
  }
};

gulp.task('lint', lint('app/scripts/**/*.js'));
gulp.task('lint:test', lint('test/spec/**/*.js', testLintOptions));

gulp.task('fileinclude', () => {
  return gulp.src('app/*.html')
    .pipe($.fileInclude({ prefix: '@@', basepath: '@file' }))
    .pipe(gulp.dest('.tmp'))
    .pipe(reload({stream: true}));
});

gulp.task('html', ['styles'], () => {
  return gulp.src('app/*.html')
    .pipe($.useref({searchPath: ['.tmp', 'app', '.']}))
    .pipe($.if('*.js', $.uglify()))
    .pipe($.if('*.css', $.cssnano()))
    //.pipe($.if('*.html', $.htmlmin()))
    .pipe($.if('*.html', $.fileInclude({prefix: '@@', basepath: '@file'})))
    .pipe(gulp.dest('dist'));
});

gulp.task('images', () => {
  return gulp.src('app/images/**/*')
    .pipe($.if($.if.isFile, $.cache($.imagemin({
      progressive: true,
      interlaced: true,
      // don't remove IDs from SVGs, they are often used
      // as hooks for embedding and styling
      svgoPlugins: [{cleanupIDs: false}]
    }))
    .on('error', function (err) {
      console.log(err);
      this.end();
    })))
    .pipe(gulp.dest('dist/images'));
});

gulp.task('fonts', () => {
  return gulp.src(require('main-bower-files')('**/*.{eot,svg,ttf,woff,woff2}', function (err) {})
    .concat('app/fonts/**/*'))
    .pipe(gulp.dest('.tmp/fonts'))
    .pipe(gulp.dest('dist/fonts'));
});

gulp.task('extras', () => {
  return gulp.src([
    'app/*.*',
    '!app/*.html'
  ], {
    dot: true
  }).pipe(gulp.dest('dist'));
});

gulp.task('clean', del.bind(null, ['.tmp', 'dist']));

gulp.task('serve', ['fileinclude', 'styles', 'fonts'], () => {
  browserSync({
    notify: false,
    port: 9000,
    server: {
      baseDir: ['.tmp', 'app'],
      routes: {
        '/bower_components': 'bower_components'
      }
    }
  });

  gulp.watch([
    'app/*.html',
    'app/scripts/**/*.js',
    'app/images/**/*',
    '.tmp/fonts/**/*'
  ]).on('change', reload);

  gulp.watch('app/**/*.html', ['fileinclude']);
  gulp.watch('app/styles/**/*.scss', ['styles']);
  gulp.watch('app/fonts/**/*', ['fonts']);
  gulp.watch('bower.json', ['wiredep', 'fonts']);
});

gulp.task('serve:dist', () => {
  browserSync({
    notify: false,
    port: 9000,
    server: {
      baseDir: ['dist']
    }
  });
});

gulp.task('serve:test', () => {
  browserSync({
    notify: false,
    port: 9000,
    ui: false,
    server: {
      baseDir: 'test',
      routes: {
        '/scripts': 'app/scripts',
        '/bower_components': 'bower_components'
      }
    }
  });

  gulp.watch('test/spec/**/*.js').on('change', reload);
  gulp.watch('test/spec/**/*.js', ['lint:test']);
});

// inject bower components
gulp.task('wiredep', () => {
  gulp.src('app/styles/*.scss')
    .pipe(wiredep({
      ignorePath: /^(\.\.\/)+/
    }))
    .pipe(gulp.dest('app/styles'));

  gulp.src('app/*.html')
    .pipe(wiredep({
      ignorePath: /^(\.\.\/)*\.\./
    }))
    .pipe(gulp.dest('app'));
});

gulp.task('build', ['lint', 'html', 'images', 'fonts', 'extras'], () => {
  return gulp.src('dist/**/*').pipe($.size({title: 'build', gzip: true}));
});

gulp.task('default', ['clean'], () => {
  gulp.start('build');
});



Categories:webdesign
Comments: 1

My 2015 in Pictures

by: Rich Hauck

2015 brought an unbalanced work load and a lot of home upgrades. There wasn’t necessarily anything wrong with last year, but I won’t deny that I’m looking forward to this upcoming year.


Categories:webdesign
Comments: 0

Christmas Card 2016

by: Rich Hauck

This year, I enlisted the help of two younger artists.

xmas2015card

xmas2015card-inner

IMG_1911

I’m not sure anyone got my Joan Miró reference…

It’s still fun to hear about people’s anticipation for these cards and how some folks collect them. If you know me and want on next year’s list give me a holler.

IMG_1950


Categories:christmas-card
Comments: 0

The TorchBearer Labels That No One Will Ever See

by: Rich Hauck

Okay, so it’s a misleading title (especially now with this post), but it sounds cool.

Before I apparently became famous as the guy in this photo, my former claim to fame was as the “TorchBearer label guy.” I’m (finally) revisiting my past identity by working on the Psycho Curry label, and I figured I’d share a set of  labels that were seen exclusively by the trade show circuit.

The good folks at Datum Storage Solutions are fans of both TorchBearer’s sauces and their labels, and they commissioned me to do two custom labels for mini-bottles for trade shows. The theme: spartans and zombies.

In what’s become a rarity in my workflow, I actually did some starting sketches on paper before moving to digital. Here’s some of the sketches along with the final product.

spartan-2

spartan-1

 

spartan

zombie


Categories:art Illustration
Comments: 0

Harrisburg’s Greenbelt in Infrared

by: Rich Hauck

 

I recently squeezed in a bike ride around the Greenbelt before the autumn’s breeze proved unbearable. I lugged along my SLR and my tripod, and while my tripod bag didn’t survive the trip, I made it out with these infrared photos.

MG_3662

I’ve always found the state hospital grounds to be some of the most tranquil parts of the ‘burg.

MG_3655

 

MG_3688

With a daylight white balance the shots come out very red (below). Personally, I find these far more interesting than converting to B&W, although I realize it’s not for everyone.

MG_3655

I once compared a color-to-black-and-white conversion against an infrared one and was able to generate pretty similar results. Trying to emulate an infrared image in Photoshop would be much more difficult, if not impossible.

 

MG_3694

 

 

I was really surprised to not be able to find an equivalent of the Channel Mixer in Adobe Photoshop’s RAW window. Tweaking the red channel yields some pretty wild results.

_MG_3670


Categories:Harrisburg photography
Tags:infrared
Comments: 0

Revisiting Vermont

by: Rich Hauck

Well, I didn’t manage to do too much traveling this summer, but I did make another trek up to Vermont as part of a beer run/bachelor party. Somehow, no matter how late I stayed up, my body had an internal alarm clock that woke me up around 6 a.m. Fortunately, I made the most of it by taking some beautiful shots of the countryside.

_MG_3610
_MG_3602_MG_3532 _MG_3543

The sunsets weren’t too shabby, either.

_MG_3549 _MG_3558 _MG_3595   IMG_1339

I did say beer, didn’t I? Part of the trip involved visiting Hill Farmstead.

IMG_1356

The ordering process has vastly improved in the course of a year. This time, I wasn’t stuck in a 3-hour line (at least on the Saturday morning when I visited). Instead, I was issued a numbered order card upon entering the brewery. The number assured my place in the queue, and they allow you to visit the tap house (for up to two pints) as you wait.

IMG_1340

I was really surprised that the tap house remained unfinished, as a wooden skeleton was already standing a year before. I can’t fault the brewery, as they’ve clearly been busy with production.

IMG_1348

Lastly, here’s a lovely picture of our group (along with items all found in the barn we rented):

IMG_3618


Categories:travel
Tags:vermont
Comments: 0

Modifying Yeoman gulp-webapp to use Browserify and React JS

by: Rich Hauck

yeoman

I’ve become a big fan of Yeoman’s gulp-webapp generator and have found myself integrating it into my regular development workflow since it handles code testing, text minification, live reloading, and image optimization.

In an effort to integrate Facebook’s React JS library I found several third-party generators, but wasn’t satisfied with any of them. Many stray from the vanilla gulp-webapp, whether it’s switching from SASS to LESS, eliminating Bower, or relying upon Grunt JS instead of Gulp.

One of the closest solutions I uncovered was a React Recipe that ships with the gulp-webapp repository. These step-by-step instructions worked fine, though it relies on your React classes being included in order of dependency. So, if you don’t place the <script> tags representing your classes in the right order within your index.html, your app will fail.

I felt that calling require() at the top of my Javascript class files to pull only the necessary dependencies was a more elegant solution. Call it nostalgia, but this is cleaner code harks back to my days of tinkering with Java and ActionScript. This approach requires Webpack or Browserify, of which I chose the latter. I should mention I came across this blog post that accomplished what I wanted to do, but it’s for a much earlier version of gulp-webapp and doesn’t work with the current version.

So here’s what I came up with:

1. Install the standard gulp-webapp by calling yo gulp-webapp in your command line.

  1. Install React via Bower: bower install --save react 
  2. Include the newly-downloaded React as a dependency in app/index.html (<script src="/bower_components/react/react.js"></script>)
  3. Install NPM dependencies: sudo npm install --save-dev browserify reactify vinyl-source-stream 
  4. Change gulpfile.js to include custom scripts() task. Task scripts() is called in serve() and html(). Task watch() has been modified to watch /.tmp and /scripts for changes. Here’s the scripts task:gulp.task('scripts', function() {
    return browserify({
    //paths: ['./app/scripts/'],
    entries: ['./app/scripts/App.js'],
    transform: ['reactify'],
    debug: true
    })
    .bundle()
    .pipe(source('main.js'))
    .pipe(gulp.dest('.tmp/scripts/'));
    });

    Basically, this task looks at App.js, converts it and all dependencies from JSX to regular JavaScript, then outputs all of the code into /tmp/scripts/main.js.

    When publishing via gulp build, it will JSHint the compiled JavaScript before copying it from /tmp into the /dist folder.

  5. Add javascript class files to /scripts directory. Delete main.js (as the gulpfile’s scripts() task will generate a main.js file). I chose *.js extensions only so that my text editor (Sublime Text 3 and Atom) would recognize the files and color the syntax.
  6. Add <div id="app"></div> to index.html, as this is where the app is being told to render itself in /app/scripts/App.js.

 

The whole thing is available on GitHub. I hope it helps someone else out. Feel free to drop me a line if there’s something that can be improved.

 


Categories:CSS javascript webdesign
Comments: 0

BarCampHbg is back. And that’s a good thing.

by: Rich Hauck

BarCampHbg7

This is a follow-up to my previous post, “The Fate of Barcamp Harrisburg“.

Well, while I was relatively comfortable coming to terms with barcamp ending, many of you were not, and that’s a good thing. I received a lot of supportive feedback, and as a result, Barcamp Harrisburg will go on for its seventh consecutive year with a new date and a new host for 2015.

Working with the great folks at The Tech Council of Central PA, BarCampHbg will help serve as a kickoff event for the week-long UPNEXTFEST. Formerly Harrisburg Startup Weekend, UPNEXTFEST helps to nurture the local and potential startup community.

This year’s camp is scheduled for Saturday, October 10, 2015 at ITT Technical Institute Harrisburg. It’s only a little ways from downtown, and along with the venue change comes relief from paid parking(!).

More info will be coming soon and posted to the BarCampHbg website. In the meanwhile, save the date. If you’re interested in sponsoring, please drop a line to info@barcamphbg.org. Hope to see you there!

 


Categories:Harrisburg javascript mobile webdesign
Comments: 6

Drawing The Burg Cover

by: Rich Hauck

The Burg June 2015

If you wander around Central Pennsylvania this month you’re likely to find a copy of The Burg at a newsstand with my work on the cover. I have been illustrating for this monthly magazine for the past few months now, and despite the inevitable time constraints of print, I’m pretty proud of my work on the June 2015 cover.

The concept started as a map that would feature local venues representing the Central Pennsylvania region. The initial list handed to me clocked in at 27 venues, including Red Rabbit, Mt. Gretna, and the Perry County Fair. I countered to refine the list, as I was concerned that too many destinations would clutter the piece (not to mention take a long time to draw!). Ultimately, I narrowed the list down and included the state capitol to help define the region.

sketch

An original rough sketch using Google Maps colors

I wasn’t provided any direction for color, so I started using colors from Google Maps. I quickly ruled this out as I became concerned that the beige backdrop would pale on newsprint. I was also concerned that the negative space would be a little boring, so I began experimenting with handwriting locations. You could say I was drawing from Paula Scher’s Maps for inspiration, though this approach ironically looks similar to what Stephen Michael Haas did for The Burg in January.

blueprint

The entire illustration was completed over a weekend in Photoshop CC 2014 on a Cintiq 22HD Touch (no paper was harmed in the making of this illustration!). I’d recently watched the documentary “Stripped” where one of the illustrators drew in blue on their second pass. I decided to try the same approach. It’s probably not too noticeable, but I sadly ran out of time and didn’t get to redraw the capitol building or Hollywood Casino as I’d sought out to do.

Cover no text

Here’s the final illustration with the text layer hidden.

I shared early drafts with some friends for feedback and one friend mentioned that it looked similar to the labels I’d done for TorchBearer Sauces. While there’s not much I can do about that (it’s my work and carries my handwriting, too), though it somehow got me thinking about Richard Diebenkorn’s Ocean Park series. As a result, I tried underpainting instead of  the solid bold colors of the sauce labels.

The finished product did have me a little nervous about which landmarks I chose to include. I anticipated people complaining on why I chose to include this coffee shop’s name over another, or why I excluded smaller attractions for larger ones. Fortunately, feedback has been good (though no one seems to recognize the barn at Fort Hunter).

I really appreciate how “The Burg” editor-in-chief Larry Binda and the lovely Megan Davis have included me in their fantastic little publication, and I’m already working on an illustration for next month’s issue.


Categories:art Harrisburg
Comments: 12

About Rich Hauck

Rich Hauck

I'm a creative technologist at Hauck Interactive, Inc. and an adjunct instructor at HACC. I live in Harrisburg, Pa. with my wife and two boys. I enjoy good coffee, Trappist beers, Orioles baseball, and good design.


Archives