/gulp-htmlbuild

Extract content from html documents and replace by build result

Primary LanguageJavaScriptMIT LicenseMIT

gulp-htmlbuild NPM version Build Status Dependency Status

Extract content from html documents and replace by build result, analog to grunt-usemin, supports css and js out of the box.

Warning

I'm still prototyping on this package so expect changes to it's API! Also, I'm open to suggestions.

Usage

First install it

npm install --save-dev gulp-htmlbuild

then add it to your gulpfile:

gulp.task('build', function () {
  gulp.src(['./index.html'])
    .pipe(htmlbuild({
      // build js with preprocessor
      js: htmlbuild.preprocess.js(function (block) {
        
        // read paths from the [block] stream and build them
        // ...
        
        // then write the build result path to it
        block.write('buildresult.js');
        block.end();
        
      })
    }))
    .pipe(gulp.dest('./build'));
});

gulp build will take index.html:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Document</title>
  </head>
  <body>
    
    <!-- htmlbuild:js -->
    <script src="js/script1.js"></script>
    <script src="js/script2.js"></script>
    <!-- endbuild -->
    
  </body>
</html>

And turn it into:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Document</title>
  </head>
  <body>
    
    <script src="buildresult.js"></script>
    
  </body>
</html>

You can find more examples in the example folder.

API

htmlbuild(options)

options

options is an object which maps targets to build functions. The build functions take a single argument, a stream which represents the block. Read from this stream to get the content of the block and write to it to replace it. The stream has the following properties:

  • {String} indent : string containing the indentation of the block directive.
  • {Array} args : string array of arguments passed in via the block directive.

htmlbuild.preprocess.js(buildFn)

a preprocessor you can use to wrap your buildfunction in. It extracts script paths from the block. In this case you also write paths to the block. They will get templated into link elements.

buildFn

a function that has the same form as a normal buildfunction, only the argument here is a stream that contains script paths. You are expected to write script paths to this stream as well.

htmlbuild.preprocess.css(buildFn)

a preprocessor you can use to wrap your buildfunction in. It extracts stylesheet paths from the block. In this case you also write paths to the block. They will get templated into link elements.

buildFn

a function that has the same form as a normal buildfunction, only the argument here is a stream that contains stylesheet paths. You are expected to write paths to this stream as well.

Extended example

example gulp file:

var gulp  = require('gulp'),
    plugins = require('gulp-load-plugins')(),
    htmlbuild = require('../lib'),
    es = require('event-stream');


// pipe a glob stream into this and receive a gulp file stream
var gulpSrc = function (opts) {
  var paths = es.through();
  var files = es.through();
  
  paths.pipe(es.writeArray(function (err, srcs) {
    gulp.src(srcs, opts).pipe(files);
  }));
  
  return es.duplex(paths, files);
};


var jsBuild = es.pipeline(
  plugins.concat('concat.js'),
  gulp.dest('./build/js')
);

var cssBuild = es.pipeline(
  plugins.concat('concat.css'),
  gulp.dest('./build/css')
);


gulp.task('build', function () {
  
  gulp.src(['./index.html'])
    .pipe(htmlbuild({
      // build js with preprocessor
      js: htmlbuild.preprocess.js(function (block) {
        
        block.pipe(gulpSrc())
          .pipe(jsBuild);
        
        block.end('js/concat.js');
        
      }),
      
      // build css with preprocessor
      css: htmlbuild.preprocess.css(function (block) {
        
        block.pipe(gulpSrc())
          .pipe(cssBuild);
        
        block.end('css/concat.css');
        
      }),
      
      // remove blocks with this target
      remove: function (block) {
        block.end();
      },
      
      // add a template with this target
      template: function (block) {
        es.readArray([
          '<!--',
          '  processed by htmlbuild (' + block.args[0] + ')',
          '-->'
        ].map(function (str) {
          return block.indent + str;
        })).pipe(block);
      }
    }))
    .pipe(gulp.dest('./build'));
  
});

it will take following html file

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Document</title>
    
    <!-- htmlbuild:css -->
    <link href="css/stylesheet1.css"/>
    <link href="css/stylesheet2.css"/>
    <!-- endbuild -->
    
  </head>
  <body>
  
    <!-- htmlbuild:template header -->
    <!-- endbuild -->
  
    <!-- htmlbuild:js -->
    <script src="js/src1.js"></script>
    <script src="js/src2.js"></script>
    <!-- endbuild -->
    
    <!-- htmlbuild:remove -->
    This will be removed in the build output
    <!-- endbuild -->
  
    <!-- htmlbuild:template footer -->
    <!-- endbuild -->

  </body>
</html>

and turn it into:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Document</title>
    
    <link rel="stylesheet" href="css/concat.css"/>
    
  </head>
  <body>
  
    <!--
      processed by htmlbuild (header)
    -->
  
    <script src="js/concat.js"></script>
    

    <!--
      processed by htmlbuild (footer)
    -->
  </body>
</html>

While concatenating stylesheets and scripts on the fly.

License

MIT License