1
0
Fork 0
You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

296 lines
8.2 KiB
JavaScript

'use strict';
// Directory name inside the patterns repo
var site = 'codesignd';
////////////////////////////////////////////////////////////////////////////////
// Node dependencies
var fs = require('fs');
var path = require('path');
// gulp and gulp plugins
var gulp = require('gulp');
var autoprefixer = require('gulp-autoprefixer');
var cleanCSS = require('gulp-clean-css');
var concat = require('gulp-concat');
var header = require('gulp-header');
var include = require('gulp-include');
var preservetime = require('gulp-preservetime');
var refresh = require('gulp-refresh');
var rename = require('gulp-rename');
var gulpSass = require('gulp-sass');
var sass = gulpSass.compiler;
var uglify = require('gulp-uglify');
// Other npm modules
var del = require('del');
// Load package.json of the patterns repo
var packageData = require('./site/patterns/package.json');
////////////////////////////////////////////////////////////////////////////////
var helpers = {};
/**
* Returns a banner for asset files
*
* @param {string} type File type of the generated file
* @return {object}
*/
helpers.banner = function(type) {
var banner = [
'/*!',
' * <%= pkg.description %>',
' * @link <%= pkg.homepage %>',
' * @copyright <%= pkg.copyright %>',
' * @license <%= pkg.license' + type + ' || pkg.license %>',
' */',
''
].join('\n');
return header(banner, {pkg: packageData});
};
/**
* Builds the CSS of the specified site
*
* @param {string} site Site name, defaults to "shared" if not given
* @param {boolean} minify Whether to minify using clean-css
* @return {stream}
*/
helpers.buildCSS = function(site, minify) {
if(!site) site = 'shared';
if(!minify) minify = false;
var sassOptions = {
functions: {
'-cdd-cachebuster($filepath)': function(filepath, done) {
var pathString = filepath.getValue();
fs.stat(__dirname + pathString, function(err, stats) {
if(err) throw err;
var mtime = Math.round(Date.parse(stats.mtime) / 1000);
var parsed = path.parse(pathString);
var filepath = parsed.dir + '/' + parsed.name + '.' + mtime + parsed.ext;
done(sass.types.String(filepath));
});
}
},
outputStyle: 'expanded'
};
// Compile the SCSS file
var stream = gulp.src('site/patterns/' + site + '/' + site + '.scss')
.pipe(gulpSass(sassOptions).on('error', gulpSass.logError))
.pipe(autoprefixer({browsers: ['> 1%']}))
.pipe(rename('index.css'))
.pipe(helpers.banner('CSS'))
.pipe(gulp.dest('assets/css'));
// Minify CSS if required
if(minify) {
stream = stream.pipe(rename('index.min.css'))
.pipe(cleanCSS())
.pipe(gulp.dest('assets/css'));
}
// Trigger LiveReload
return stream.pipe(refresh());
};
/**
* Builds the JS of the specified site
*
* @param {string} site Site name, defaults to "shared" if not given
* @param {boolean} minify Whether to minify using UglifyJS
* @return {stream}
*/
helpers.buildJS = function(site, minify) {
if(!site) site = 'shared';
if(!minify) minify = false;
var src = ['site/patterns/shared/**/*.js', '!site/patterns/shared/polyfills.js'];
if(site !== 'shared') {
src.push('site/patterns/' + site + '/**/*.js');
src.push('!site/patterns/' + site + '/polyfills.js');
}
// Concat the JS files
var stream = gulp.src(src)
.pipe(concat('index.js'))
.pipe(include({includePaths: __dirname + '/node_modules'}))
.pipe(helpers.banner('JS'))
.pipe(gulp.dest('assets/js'));
// Minify JS if required
if(minify) {
stream = stream.pipe(rename('index.min.js'))
.pipe(uglify({output: {comments: 'some'}}))
.pipe(gulp.dest('assets/js'));
}
// Trigger LiveReload
return stream.pipe(refresh());
};
/**
* Builds the polyfills JS of the specified site
*
* @param {string} site Site name, defaults to "shared" if not given
* @param {boolean} minify Whether to minify using UglifyJS
* @return {stream}
*/
helpers.buildPolyfillsJS = function(site, minify) {
if(!site) site = 'shared';
if(!minify) minify = false;
var src = ['site/patterns/shared/polyfills.js'];
if(site !== 'shared') src.push('site/patterns/' + site + '/polyfills.js');
// Concat the JS files
var stream = gulp.src(src, {allowEmpty: true})
.pipe(concat('polyfills.js'))
.pipe(include({includePaths: __dirname + '/node_modules'}))
.pipe(helpers.banner('JS'))
.pipe(gulp.dest('assets/js'));
// Minify JS if required
if(minify) {
stream = stream.pipe(rename('polyfills.min.js'))
.pipe(uglify({output: {comments: 'some'}}))
.pipe(gulp.dest('assets/js'));
}
// Trigger LiveReload
return stream.pipe(refresh());
};
/**
* Copies all files matching a specified pattern to the assets dir
* Removes folder hierarchies so make sure that each file has a unique name!
*
* @param {string} site Site name, defaults to "shared" if not given
* @param {string} pattern Something like "*.{jpg,svg}"
* @param {string} dest Either "fonts" or "img"
* @return {stream}
*/
helpers.copyFiles = function(site, pattern, dest) {
if(!site) site = 'shared';
var src = ['site/patterns/shared/**/' + pattern];
if(site !== 'shared') src.push('site/patterns/' + site + '/**/' + pattern);
return gulp.src(src, {since: gulp.lastRun(dest)})
.pipe(rename({dirname: ''})) // Flat hierarchy
.pipe(gulp.dest('assets/' + dest))
.pipe(preservetime())
.pipe(refresh());
};
////////////////////////////////////////////////////////////////////////////////
/**
* Compiles the CSS file of the current site
*/
gulp.task('css', function() {
return helpers.buildCSS(site);
});
/**
* Compiles and minifies the CSS file of the current site
*/
gulp.task('css.min', function() {
return helpers.buildCSS(site, true);
});
/**
* Combines the JS files of the current site
*/
gulp.task('js', function() {
return helpers.buildJS(site);
});
/**
* Combines and minifies the JS files of the current site
*/
gulp.task('js.min', function() {
return helpers.buildJS(site, true);
});
/**
* Combines the polyfills JS files of the current site
*/
gulp.task('polyfills', function() {
return helpers.buildPolyfillsJS(site);
});
/**
* Combines and minifies the polyfills JS files of the current site
*/
gulp.task('polyfills.min', function() {
return helpers.buildPolyfillsJS(site, true);
});
/**
* Copies all webfonts to assets/fonts
*/
gulp.task('fonts', function() {
return helpers.copyFiles(site, '*.{woff,woff2,eot}', 'fonts');
});
/**
* Copies all images to assets/img
*/
gulp.task('img', function() {
return helpers.copyFiles(site, '*.{jpg,png,svg,ico}', 'img');
});
/**
* Copies prism.js components to assets/js/prism
*/
gulp.task('prismjs', function() {
return gulp.src('node_modules/prismjs/components/*')
.pipe(gulp.dest('assets/js/prism'));
});
/**
* Builds everything except the minified files for local development
*/
gulp.task('default', gulp.series(gulp.parallel('fonts', 'img'), gulp.parallel('css', 'js', 'polyfills', 'prismjs')));
/**
* Watches for changes
*/
function watchwait() {
refresh.listen();
gulp.watch('site/patterns/**/*.scss', gulp.series('css'));
gulp.watch('site/patterns/**/*.js', gulp.series('js'));
gulp.watch('site/patterns/*/polyfills.js', gulp.series('polyfills'));
gulp.watch('site/patterns/**/*.{woff,woff2,eot}', gulp.series('fonts'));
gulp.watch('site/patterns/**/*.{jpg,png,svg,ico}', gulp.series('img'));
gulp.watch(['content/**/*.txt', 'site/**/*.{php,yml}']).on('change', refresh.changed);
}
gulp.task('watch', gulp.series('default', watchwait));
/**
* Cleans built files
*/
gulp.task('clean', function() {
return del('assets/*/*');
});
/**
* Builds everything for production
* WARNING: Deletes some source files, only run this after committing your files
*/
function prodclean() {
return del(['node_modules', 'gulpfile.js', 'site/patterns/*/', '!site/patterns/{shared,' + site + '}']);
}
gulp.task('prod', gulp.series('clean', gulp.parallel('fonts', 'img'), gulp.parallel('css.min', 'js.min', 'polyfills.min', 'prismjs'), prodclean));