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:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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:
- gulp build
- 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.Task( ‘nghtml2js‘, 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/*.html‘, ‘ModuleName‘,‘/templates/‘,‘resources/assets/js/‘,‘ModuleName-tpls.js‘)
Arguments:
- 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.
- 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’]);
- 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
- String – resources/assets/js/ relative to Laravel project’s root directory to place built js file into.
- 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!