Gulp Inject: The Web Framework for Hipsters

Today’s web frameworks are powerful champions that can serve the highest quality user experience featuring full interactive web apps with all the bells and whistles you didn’t know you needed. Seriously, frameworks like Angular and React are really great tools when you have a hefty project and want to provide the best user interaction experience.

That kind of power is not for everyone. With great power comes a great learning curve, huge amounts of boilerplate framework-specific code, and the maintenance required to keep your dependencies updated.

Efficiency vs. Time

Learning Curve
A huge framework (Angular, React) comes with a huge learning curve and boilerplate code that can't always be avoided. This drastically reduces your efficiency for the ramp up time.
WARNING: Not actual science

I think most developers will agree that these frameworks generally increase efficiency in medium to large projects over time. They are flexible, maintainable, and after learning how they work they can make a lot of interactions with the DOM easier to manage. But what if you have a relatively smaller project with little user interaction? For example, a single page website listing information about a small company or an aspiring tech blog like this one.

I tried out a new tool called Gulp-Inject that can inject pieces of reusable HTML into as many web pages as you need. It’s an HTML comment based framework that’s super easy to use and understand.

Example time!

Here are some common reusable pieces of HTML, or partials, you would want to inject into your pages

partials/head.html

<head>
  <title>JBurchard.com | Blog</title>
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <meta name="keywords" content="Josiah Burchard, Software Developer, JBurchard">
  <meta name="twitter:card" content="summary">
  <meta name="twitter:site" content="@josiahburchard">
  <meta name="twitter:image" content="https://jburchard.com/images/josiah-burchard.jpg">
  <meta property="og:type" content="website">
  <meta property="og:site_name" content="JBurchard.com">
  <meta property="og:image" content="https://jburchard.com/images/josiah-burchard.jpg">
  <meta property="og:image:width" content="200">
  <meta property="og:image:height" content="200">
  <link rel="stylesheet" href="/lib/css/main.css" />
  <link rel="stylesheet" href="/app.css" />
  <link rel="stylesheet" href="/lib/css/fontawesome.min.css" />
</head>

partials/footer.html

<footer>
  <ul class="footer-menu">
    <li>&copy; JBurchard.com. All rights reserved.</li>
    <li>Footers always make me think of feet</li>
    <li>Feet are kind of gross, right?</li>
  </ul>
</footer>

Now when you are writing your blog posts, you can insert these partials wherever you want them with a special HTML comment.

blog.html

blog.html
<!DOCTYPE HTML>
<html>
<!-- inject:header:html -->
<!-- endinject -->
<div>Hey all. Nice to see you reading this blog post.</div>
<!-- inject:footer:html -->
<!-- endinject -->
</html>

Alright, is it safe to say you’re intrigued? There’s just one more step to use Gulp-Inject, you have to run a script called a Gulp File. This script will use a couple tools called Node and Gulp to analyze your code and inject the right documents.

Here’s just a snippet, but you can view the full thing on Github or Live.

+--gulpFile.js
+--package.json
+--src
|  \--index.html
|  \--sales.html
|  \--assets
|     \--app.js
|     \--styles.css
|  \--partials
|     \--footer.html
|     \--head.html
|     \--header.html
|     \--scripts.html

gulpFile.js

var gulp = require('gulp');
var inject = require('gulp-inject');

// Define tasks for gulp to execute
gulp.task('default', ['inject', 'assets'], function() { });

gulp.task('inject', function() {
    
    // Grab all the html files, except the partials
    return gulp.src(['src/**/*.html', '!src/partials/**'])

        // Inject the partials into the regular html files
        .pipe(inject(gulp.src(['src/partials/head.html']), createInjectOptions('head')))
        .pipe(inject(gulp.src(['src/partials/header.html']), createInjectOptions('header')))
        .pipe(inject(gulp.src(['src/partials/footer.html']), createInjectOptions('footer')))
        .pipe(inject(gulp.src(['src/partials/scripts.html']), createInjectOptions('scripts')))

        // Copy the results into dist/
        .pipe(gulp.dest('dist/'));
});

gulp.task('assets', function() {
    // Copy assets (js, css) into dist/
    return gulp.src(['src/assets/**'])
        .pipe(gulp.dest('dist/'));
});

function createInjectOptions(tagName) {
    return {
        starttag: `<!-- inject:${tagName}:{{ext}} -->`,
        transform: function (filePath, file) {
            return file.contents.toString('utf8')
        }
    };
}

index.html

<!DOCTYPE HTML>
<html>

<head>
  <title>Blog de JBurchard</title>
  <!-- inject:head:html -->
  <!-- endinject -->
</head>

<body>
  <!-- inject:header:html -->
  <!-- endinject -->

  <div class="container">
    <div class="jumbotron">
      <h3>Welcome to the homepage, ya'll.</h3>
    </div>
  </div>

  <!-- inject:footer:html -->
  <!-- endinject -->

  <!-- inject:scripts:html -->
  <!-- endinject -->
</body>

</html>

sales.html

<!DOCTYPE HTML>
<html>

<head>
  <title>Sales Department | Blog de JBurchard</title>
  <!-- inject:head:html -->
  <!-- endinject -->
</head>

<body>
  <!-- inject:header:html -->
  <!-- endinject -->

  <div class="container">
    <div class="jumbotron">
      <h3>Hey, uh. Want to buy something?</h3>
    </div>
  </div>

  <!-- inject:footer:html -->
  <!-- endinject -->

  <!-- inject:scripts:html -->
  <!-- endinject -->
</body>

</html>

There’s no bells and whistles to this approach, but it is incredibly easy to see exactly what is going on in the whole project. Nothing is hidden in the internals of a massive framework. So if your needs are too small for a framework giant, or if you like the hipster/hacker way of going against the crowd, build something with Gulp-Inject.


I'm sure there's plenty of programming hipsters out there looking to try something different. Let me know what you're up to at josiah@jburchard.com or @JosiahBurchard on Twitter

January 2017