adgile
Version:
An easy-to-use automated front-end setup.
173 lines (151 loc) • 6.06 kB
JavaScript
/**
* A submodule for running the `adg build` task,
* responsible for compiling the HTML-templates and exporting them to the export folder
* @module task.misc
*/
const settings = require('../settings.default'),
helpers = require('../helpers/index'),
chalk = require('chalk'),
gulp = require('gulp'),
path = require('path'),
globule = require('globule'),
_ = require('lodash'),
bsTask = require('../tasks/task-browsersync'),
through2 = require('through2'),
plugins = require('gulp-load-plugins')({
config: path.join(__dirname, '../package.json')
});
function runTask() {
helpers.verbose(chalk.grey('Running task "templates"'));
// If assembly is off, export all folders and files
if (!config.assemble_templates) {
gulp.src(['templates/**/*', '!templates/**/_*'])
.pipe(gulp.dest(config.export_templates));
}
// Find number of "root" templates to parse and keep count
let templatesToParse = ['templates/**/*.*', '!templates/partials/**/*.*', '!templates/layout/**/*.*', '!templates/**/_*'];
let partialsToParse = helpers.getAllPartials('partials', 'layout');
let numTemplates = globule.find(templatesToParse).length,
count = 0;
// Go over all root template files
return gulp.src(templatesToParse)
.pipe(plugins.data((htmlFile) => {
let
// Extract bits from filename
baseName = path.basename(htmlFile.path),
baseDir = path.dirname(htmlFile.path).replace(path.join(settings.cwd, 'templates'), ''),
nameParts = baseName.split('.'),
ext = _.without(nameParts, _.first(nameParts)).join('.'),
viewBaseName = _.last(nameParts[0].split('view-')),
// Make sure Windows paths work down below
cwdParts = settings.cwd.replace(/\\/g, '/').split('/'),
// Make a collection of file globs
// Production will get 1 file only
// Development gets raw base files
// The order is important! Libraries should be injected first. Main JS-files last.
injectItems = settings.isProduction ?
[
config.export_assets + '/' + settings.assetsFolder + '/js/core-libs*.min.js',
config.export_assets + '/' + settings.assetsFolder + '/js/view-' + viewBaseName + '*.min.js'
]
:
[
config.export_assets + '/' + settings.assetsFolder + '/js/libs/jquery*.js',
(settings.isProduction ? '!' : '') + config.export_assets + '/' + settings.assetsFolder + '/js/libs/dev/*.js',
config.export_assets + '/' + settings.assetsFolder + '/js/libs/*.js',
config.export_assets + '/' + settings.assetsFolder + '/js/**/*.js',
'!' + config.export_assets + '/' + settings.assetsFolder + '/**/_*.js',
]
;
// Include the css
injectItems.push(config.export_assets + '/' + settings.assetsFolder + '/css/main*.css');
injectItems.push(config.export_assets + '/' + settings.assetsFolder + '/css/view-' + viewBaseName + '*.css');
// // Put items in a stream and order dependencies
injectItems = gulp.src(injectItems)
.pipe(plugins.plumber())
.pipe(plugins.ignore.include(function (file) {
var fileBase = path.basename(file.path);
// Exclude filenames with "view-" not matching the current view
if (fileBase.indexOf('view-') > -1 && fileBase.indexOf('.js') > -1 && fileBase.indexOf(viewBaseName) < 0) {
return false;
}
// Pass through all the other files
return true;
}))
.pipe(plugins.deporder(baseName));
// // On the current template
gulp.src(path.join('templates', baseDir, baseName.replace(/^\/?|^\\/, '')), { base: settings.templatesFolder })
.pipe(plugins.plumber())
// Piping plugins.newer() blocks refreshes on partials and layout parts :(
//.pipe(plugins.newer(config.export_templates + '/' + baseName))
.pipe(plugins.if(config.assemble_templates, plugins.compileHandlebars({
templateName: baseName
}, {
partials: partialsToParse,
helpers: {
equal: function (v1, v2, options) {
return (v1 == v2) ? options.fn(this) : options.inverse(this);
}
}
})))
.on('error', error => {
console.error(chalk.red('Error: ' + error.message));
})
.pipe(plugins.inject(injectItems, {
ignorePath: [
_.without(cwdParts, cwdParts.splice(-1)[0]).join('/')
].concat(config.export_assets.split('/')),
addRootSlash: false,
addPrefix: config.template_asset_prefix || '',
removeTags: true,
quiet: true,
relative: true,
transform: (filePath) => {
let ext = filePath.split('.').pop();
let newPath = filePath.replace('../' + config.export_assets + '/', '');
let tag = '';
switch (ext) {
case 'css':
tag = '<link rel="stylesheet" href="' + newPath + (config.css_timestamp || settings.isProduction ? '?v=' + Date.now() : '') + '">';
break;
case 'js':
tag = '<script src="' + newPath + (config.js_timestamp || settings.isProduction ? '?v=' + Date.now() : '') + '"></script>';
break;
default:
break;
}
return tag;
}
}))
.pipe(plugins.if(config.minifyHTML && settings.isProduction, plugins.htmlmin(settings.htmlminOptions)))
.pipe( through2.obj(( file, enc, cb ) => {
let date = new Date();
file.stat.atime = date;
file.stat.mtime = date;
cb( null, file );
}))
.pipe(gulp.dest(config.export_templates))
.on('end', function () {
// Since above changes are made in a tapped stream
// We have to count to make sure everything is parsed
count = count + 1;
if (count == numTemplates) {
// Reload when serving
if (settings.livereload) {
bsTask.refresh(false);
}
return false;
}
});
if(config.hint_html && ext === 'html') {
gulp.src(config.export_templates + '/' + baseName)
.pipe(plugins.htmlhint({ htmlhintrc: '.htmlhintrc.json' }))
.pipe(plugins.htmlhint.reporter())
}
}))
;
}
module.exports = {
runTask
}