Developer tutorials Automate your workflow with Gulp fromasingletemplate.Inthiscase,onepageforeachcar make,whichdisplaysalistofavailablemodels.Createa newtaskcalled‘models-list’andgrabthesamecardata file,deletingcachefromanypreviousbuildslikebefore. gulp.task(‘models-list’, function() { console.log(‘Generating car pages ’); delete require.cache[require. resolve(`./${dataDev}/cars.json`)]; let config = require(`./${dataDev}/cars. json`); }); 20. Rendernewpages–part2 We’llnowloopthroughthemakesfromthecardata usingamapfunction.Bydefault,therearethreedifferent makesinthecardata,sotheloopshouldrunthreetimes. Foreachone,we’llfirstpassthetemplatetoNunjucksand injectthecardata,thenrenameittoincludethemakein itsfilenamebeforefinallysendingthecompiledHTMLto the ‘htmlDist’ directory. config[‘makes’].map(function(make) { return gulp.src(`${htmlDev}/template. html`) .pipe(nunjucks.compile({ date: config[‘date’], make: make.name, cars: make.cars })) .pipe(rename({basename: `${make.name.toLowerCase()}-leaseprices`})) .pipe(gulp.dest(htmlDist)); }); 21. Automating XML sitemaps Next, we’ll use Gulp to generate an XML sitemap based on our statically generated HTML pages. Typically, we would need one for SEO purposes, and having to update it every time a page is added would be a pain. Install ‘gulp-sitemap’ and include it as a dependency called ‘sitemap’ in gulpfile. 22. Create sitemap task – part 1 Create a new task called ‘sitemap’ and within it, use ‘src()’ to grab any compiled HTML files from the ‘htmlDist’ directory. To save a bit of processing time, we’ll set the method’s ‘read’ option to false, meaning it won’t read each files contents, instead only registering its existence. gulp.task(‘sitemap’, function() { console.log(‘Generating sitemap ’); return gulp.src(`${htmlDist}/*.html`, { read: false }) }); 23. Create sitemap task – part 2 We need to pass the compiled HTML files to the sitemap plugin so they can be registered. The options we’re configuring here largely correspond to tags within an XML sitemap page entry. One thing to note is that in places, we’re using regex through the ‘replace()’ method. This removes the ‘.html’ file extension where visible, as typically,onalivewebserver,thesewouldn’tbeusedin web addresses. .pipe(sitemap({ siteUrl: ‘http://www.example.com’, mappings: [{ pages: [ ‘**/*.html’ ], changefreq: ‘monthly’, lastmod: Date.now(), hreflang: [{ lang: ‘en-GB’, getHref(siteUrl, file, lang, loc) { return siteUrl + file. replace(/\.\w+$/, ‘’); } }], getLoc(siteUrl, loc, entry) { return loc.replace(/\.\w+$/, ‘’); } }] })) .pipe(gulp.dest(htmlDist)); 24. Copy static files Inanybuildsystem,sometimestheonlythingweneed to do with certain files is copy them from directory A to directoryB.Inthisproject,there’sacollectionoffonts whereweneedtodojustthat.Createanewtaskcalled ‘copy’,callthe‘src()’methodandgrabanythingin‘fonts’ within the ‘dev’ directory, before using the ‘dest()’ method to copy them to ‘dist’. gulp.task(‘copy-fonts’, function() { console.log(‘Copying fonts ’); return gulp.src(`${dev}/fonts/**`) .pipe(gulp.dest(`${dist}/fonts`)); }); 25. Createawebserver Beingabletoeasilycreateasimplewebservertoserve ourprojectfromwouldbeabigconvenience.Thisis something we can do in Gulp with the ‘gulp-webserver plugin’,whichweshouldinstallandthenlistasa dependency called ‘webserver’ in gulpfile. Under the Production Tasks header, add the task below. We’llsettheplugin’s‘livereload’optiontotrue,sothat when changes are made, the page automatically refreshes in the browser. gulp.task(‘serve’, function() { console.log(“Serving the project ”); gulp.src(`${dist}`).pipe(webserver({ livereload: true })); }); 26. Install run-sequence Nowwehaveallofourtasksinplace,itwouldbeuseful ifwecouldrunthemallwithoneeasycommand,rather thanbeingforcedtorunthemindividually. Themostreadablewayforustodothisrequiresa plugin called ‘run-sequence’. Install it in the usual mannerandincludeitasaprojectdependencycalled ‘runSequence’.Next,createanewtaskunderthe ProductionTasksheadercalled‘build’. gulp.task(‘build’, function() { }); 27. Creating the build task With run-sequence, we can define whether tasks should run synchronously or asynchronously, which is helpful when one task (Such as UnCSS) depends on another being completed first (such as SASS). Gulp comes with this kind of functionality out of the box in the form of task dependencies, but run-sequence enables us to define this behaviour in a much more obvious, readable way, in large tasks. Add the snippet below to the build task. Tasks passed on their own run synchronously, while tasks passed in an array all run asynchronously. runSequence( ‘deleteDist’, [‘makes-list’, ‘models-list’, ‘sass’, ‘js’, ‘copy-fonts’, ‘images’], [‘uncss’, ‘sitemap’] ); 28. Dev task – part 1 So far, we have created a build task which does exactly that, build the task. One issue with this is that during development, we’ll keep having to run this or individual tasksaswemakechangestoourfiles,aswellasserve our project. Let’s create another task called ‘dev’ that automates all of this. You may notice that before the task’s function, we’re adding an array mentioning the ‘build’ and ‘serve’ tasks, which tells Gulp to run these first. These are the same tasks dependencies mentioned in Step 27, and are more suited to this simple use. gulp.task(‘dev’, [‘build’, ‘serve’], function() { }); 29. Dev task – part 2 Next, we’ll use a method belonging to Gulp called ‘watch()’. This keeps an eye on any files we pass to it via the first parameter, and if they change, runs the task passed in the second. This removes the need for us to manually run tasks as we develop the project. Add these watch tasks to ‘dev’ and that should cover everything. gulp.watch([`${htmlDev}/**/*.html`, `${dev}/data/cars.json`], [‘makes-list’, ‘models-list’]); gulp.watch(`${imgDev}/*.+(png|jpg|jpeg|gif)` ,[‘images’]); gulp.watch(`${sassDev}/**/*.scss`,[‘sass’]); gulp.watch(`${jsDev}/**/*.js`,[‘js’]); 30. Run dev task Finally, run the dev task in terminal with ‘gulp dev’ and watch as the project is built and a server is created at localhost:8000. From then on, if we change any of the files which are being watched, the appropriate task will then run and recompile your edited file. Congratulations! You now have a build system powered by Gulp.js. 84 _________________________________________________tutorial
Special offer for readers in North America 6issuesFREE FREE resource downloads eve y issue When you subscribe T stu tun unn ly magazine ed to design develop ng websites Order hotline +44 (0) 344 848 2852 Online at myfavouritemagazines.co.uk/WEDPQ17 *Terms and conditions This is a US subscription offer. 6 free issues refers to the USA newsstand price of $14.99 for 13 issues being $194.87, compared with $103.20 for a subscription. You will receive 13 issues in a year. You can write to us or call us to cancel your subscription within 14 days of purchase. Payment is non-refundable after the 14 day cancellation period unless exceptional circumstances apply. Your statutory rights are not affected. Prices correct at point of print and subject to change. Full details of the Direct Debit guarantee are available upon request. <strong>UK</strong> calls will cost the same as full terms and conditions please visit: bit.ly/magtandc Offer ends March 31 <strong>2018</strong>. Expires 31 March <strong>2018</strong>