Laravel 5.3 Elixir nghtml2js extenstion with watcher

Today I’ll share experience of creating custom extension for Elixir gulp based build system on Laravel 5.3

There are countless ways of gulp usage, Elixir is built to simplify common gulp tasks implementation.  If you develop AngularJs  powered application you’ll definitelly will wan’t to complile your directives/components templates into Angular module and minify it to preload them to template cache.

Here’s finall solution and example of usage:

const elixir = require('laravel-elixir');
elixir.extend('nghtml2js', function(sources,moduleName,prefix,destFolder,destfileName) {
const ngHtml2Js = require("gulp-ng-html2js");
const htmlmin = require('gulp-htmlmin');
const concat = require("gulp-concat");
const uglify = require("gulp-uglify");
new elixir.Task('nghtml2js',function(){
return gulp.src(sources)
.pipe(htmlmin({
collapseWhitespace: true,
includeAutoGeneratedTags: false
}))
.pipe(ngHtml2Js({
moduleName: moduleName,
prefix: prefix
}))
.pipe(concat(destfileName))
.pipe(uglify())
.pipe(gulp.dest(destFolder));
}).watch(sources);
});
// usage example
elixir(mix => {
// mix styles and scripts then call this snippet to compile html templates into angularjs module
mix.nghtml2js('resources/assets/js/components/*.html','ModuleName','/templates/','resources/assets/js/','ModuleName-tpls.js')
});

To use it just copy\paste lines: 4 – 25 of this snippet containing ready to use Elixir extension into your gulpfile.js

Also you need to install additional gulp packages via:

npm install gulp-ng-html2js gulp-htmlmin  –save-dev

 

Lets dig into it:

First we need to understand main tasks for this extension:

  1. gulp build
  2. gulp watch

Elixir.extend  method recieves 2 arguments, first is your extension name in our case nghtml2js will call it via this name in our build script, the second argument is our gulp task function, it can recieve any numbers of args itself.

Important thing is how we implement gulp task with elixir.

new elixir.Tasknghtml2js, function(){  ……  } ).watch(sources);

Again  it recieves 2 arguments: task name and implementation function.

Another important thing is chaining .watch() as you need it to be able to track changes of your sources to rebuild, it takes same argument as string or array of strings of source file paths as usuall gulp task or module.

If you need to implement your custom Elixir extension use it as boilerplate as when I’ve done it I found watching implementation less documented.

There are some notes on gulp-htmlmin module settings:

collapseWhitespace: true  – needed for better html minification as it willl strip unneeded spaces.

but even more important and a bit tricky is this one:

includeAutoGeneratedTags: false  – false because if true it will create error on selfclosing tags – on input tags for example as it will try to automatically close them, as a result your templates could be broken.

Usage and parameters of nghtml2js extension:

mix.nghtml2js(resources/assets/js/components/*.htmlModuleName,/templates/,resources/assets/js/,ModuleName-tpls.js)

Arguments:

  1.  String or array of strings – standard paths of source files to build from resources/assets/js/components/*.html  – in this case it’s Laravel project’s root based path with wildcard getting all .html  files in directory containing our AngularJS templates.
  2. String ModuleName – Name for you module to be build for AndularJS you can specify it same as your app’s module name for example ClientApp  or complile templates in separate module and later link it as dependency to your AngularJS module app, like angular.module(‘ClientApp’,[‘Client.templates’]);
  3. String – /templates/  it is a path prefix to reference template files in your directives and components for example  in your component declaration –templateUrl:’/templates/yourCustomComponent.html’ and your component’s template source will be in resources/assets/js/components/yourCustomComponent.html 
  4. String – resources/assets/js/ relative to Laravel project’s root  directory to place built js file into.
  5. String – ModuleName-tpls.js  destination file name, so full path will be resources/assets/js/ModuleName-tpls.js  later you can add this file to mix.scripts  elixir task files array as ‘ModuleName-tpls.js’  to compile your templates module into complete js bundle. To achieve this place mix.nghtml2js()  task before mix.scripts() so it will be built first and them compiled into complete bundle.

Happy codding!

Leave a Reply

Your email address will not be published. Required fields are marked *