Skip to content

Instantly share code, notes, and snippets.

@renestalder
Created June 7, 2017 16:42
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save renestalder/89d8d701de079d520aaa680347b53b09 to your computer and use it in GitHub Desktop.
Save renestalder/89d8d701de079d520aaa680347b53b09 to your computer and use it in GitHub Desktop.
Patternlab Gulp 4
/******************************************************
* PATTERN LAB NODE
* EDITION-NODE-GULP
* The gulp wrapper around patternlab-node core, providing tasks to
* interact with the core library and move supporting frontend assets.
******************************************************/
import gulp from 'gulp';
import path from 'path';
import browserSyncLib from 'browser-sync';
import minimist from 'minimist';
import chalk from 'chalk';
import patternlabNode from 'patternlab-node';
const config = {
paths: {
source: {
root: './source/',
patterns: './source/_patterns/',
data: './source/_data/',
meta: './source/_meta/',
annotations: './source/_annotations/',
styleguide: './node_modules/styleguidekit-assets-default/dist/',
patternlabFiles: './node_modules/styleguidekit-mustache-default/views/',
js: './source/js',
images: './source/images',
fonts: './source/fonts',
css: './source/css/'
},
'public': {
root: './public/',
patterns: './public/patterns/',
data: './public/styleguide/data/',
annotations: './public/annotations/',
styleguide: './public/styleguide/',
js: './public/js',
images: './public/images',
fonts: './public/fonts',
css: './public/css'
}
},
styleGuideExcludes: [],
defaultPattern: 'all',
defaultShowPatternInfo: false,
cleanPublic: true,
patternExtension: 'mustache',
'ignored-extensions': [
'scss',
'DS_Store',
'less'
],
'ignored-directories': [
'scss'
],
debug: false,
ishControlsHide: {
s: false,
m: false,
l: false,
full: false,
random: false,
disco: false,
hay: true,
mqs: false,
find: false,
'views-all': false,
'views-annotations': false,
'views-code': false,
'views-new': false,
'tools-all': false,
'tools-docs': false
},
ishMinimum: '240',
ishMaximum: '2600',
patternStateCascade: [
'inprogress',
'inreview',
'complete'
],
patternStates: {},
patternExportPatternPartials: [],
patternExportDirectory: './pattern_exports/',
cacheBust: true,
starterkitSubDir: 'dist',
outputFileSuffixes: {
rendered: '.rendered',
rawTemplate: '',
markupOnly: '.markup-only'
},
cleanOutputHtml: true
};
const patternlab = patternlabNode(config);
const argv = minimist(process.argv.slice(2));
const browserSync = browserSyncLib.create();
const defaultTask = gulp.series(build);
export const assets = gulp.series(
copyJs,
copyImg,
copyFavicon,
copyFont,
copyCss,
copyStyleguide,
copyStyleguideCss
);
export const build = gulp.series(assets, compile);
export const connect = gulp.series(server);
export const watch = gulp.series(compile, watchTask);
export const serve = gulp.series(compile, server, watchTask);
export default defaultTask;
/******************************************************
* COPY TASKS - stream assets from source to destination
******************************************************/
// JS copy
export function copyJs() {
return gulp.src('**/*.js', {cwd: normalizePath(paths().source.js)} )
.pipe(gulp.dest(normalizePath(paths().public.js)));
}
// Images copy
export function copyImg() {
return gulp.src('**/*.*',{cwd: normalizePath(paths().source.images)} )
.pipe(gulp.dest(normalizePath(paths().public.images)));
}
// Favicon copy
export function copyFavicon() {
return gulp.src('favicon.ico', {cwd: normalizePath(paths().source.root)} )
.pipe(gulp.dest(normalizePath(paths().public.root)));
}
// Fonts copy
export function copyFont() {
return gulp.src('*', {cwd: normalizePath(paths().source.fonts)})
.pipe(gulp.dest(normalizePath(paths().public.fonts)));
}
// CSS Copy
export function copyCss() {
return gulp.src(normalizePath(paths().source.css) + '/*.css')
.pipe(gulp.dest(normalizePath(paths().public.css)))
.pipe(browserSync.stream());
}
// Styleguide Copy everything but css
export function copyStyleguide() {
return gulp.src(normalizePath(paths().source.styleguide) + '/**/!(*.css)')
.pipe(gulp.dest(normalizePath(paths().public.root)))
.pipe(browserSync.stream());
}
// Styleguide Copy and flatten css
export function copyStyleguideCss() {
return gulp.src(normalizePath(paths().source.styleguide) + '/**/*.css')
.pipe(gulp.dest(function (file) {
//flatten anything inside the styleguide into a single output dir per http://stackoverflow.com/a/34317320/1790362
file.path = path.join(file.base, path.basename(file.path));
return normalizePath(path.join(paths().public.styleguide, '/css'));
}))
.pipe(browserSync.stream());
}
/******************************************************
* PATTERN LAB CONFIGURATION - API with core library
******************************************************/
/**
* Performs the actual build step. Accomodates both async and sync
* versions of Pattern Lab.
* @param {function} done - Gulp done callback
*/
export function compile(done) {
const buildResult = patternlab.build(() => {}, getConfiguredCleanOption());
// handle async version of Pattern Lab
if (buildResult instanceof Promise) {
return buildResult.then(done);
}
// handle sync version of Pattern Lab
done();
return null;
}
export function patternlabVersion(done) {
patternlab.version();
done();
}
export function patternlabHelp(done) {
patternlab.help();
done();
}
export function patternsOnly(done) {
patternlab.patternsonly(done, getConfiguredCleanOption());
}
export function liststarterkits(done) {
patternlab.liststarterkits();
done();
}
export function loadStarterKit(done) {
patternlab.loadstarterkit(argv.kit, argv.clean);
done();
}
export function installPlugin(done) {
patternlab.installplugin(argv.plugin);
done();
}
/******************************************************
* SERVER AND WATCH TASKS
******************************************************/
// watch task utility functions
function getSupportedTemplateExtensions() {
let engines = require('./node_modules/patternlab-node/core/lib/pattern_engines');
return engines.getSupportedFileExtensions();
}
function getTemplateWatches() {
return getSupportedTemplateExtensions().map(function (dotExtension) {
return normalizePath(paths().source.patterns, '**', '*' + dotExtension);
});
}
/**
* Reloads BrowserSync.
* Note: Exits more reliably when used with a done callback.
*/
function reload(done) {
browserSync.reload();
done();
}
/**
* Reloads BrowserSync, with CSS injection.
* Note: Exits more reliably when used with a done callback.
*/
function reloadCSS(done) {
browserSync.reload('*.css');
done();
}
function watchTask() {
const watchers = [
{
name: 'CSS',
paths: [normalizePath(paths().source.css, '**', '*.css')],
config: { awaitWriteFinish: true },
tasks: gulp.series('pl-copy:css', reloadCSS)
},
{
name: 'Styleguide Files',
paths: [normalizePath(paths().source.styleguide, '**', '*')],
config: { awaitWriteFinish: true },
tasks: gulp.series('pl-copy:styleguide', 'pl-copy:styleguide-css', reloadCSS)
},
{
name: 'Source Files',
paths: [
normalizePath(paths().source.patterns, '**', '*.json'),
normalizePath(paths().source.patterns, '**', '*.md'),
normalizePath(paths().source.data, '**', '*.json'),
normalizePath(paths().source.fonts, '**', '*'),
normalizePath(paths().source.images, '**', '*'),
normalizePath(paths().source.js, '**', '*'),
normalizePath(paths().source.meta, '**', '*'),
normalizePath(paths().source.annotations, '**', '*')
].concat(getTemplateWatches()),
config: { awaitWriteFinish: true },
tasks: gulp.series(compile, reload)
}
];
watchers.forEach(watcher => {
console.log('\n' + chalk.bold('Watching ' + watcher.name + ':'));
watcher.paths.forEach(p => console.log(' ' + p));
gulp.watch(watcher.paths, watcher.config, watcher.tasks);
});
console.log();
}
function server(done) {
browserSync.init({
server: {
baseDir: normalizePath(paths().public.root)
},
snippetOptions: {
// Ignore all HTML files within the templates folder
blacklist: ['/index.html', '/', '/?*']
},
notify: {
styles: [
'display: none',
'padding: 15px',
'font-family: sans-serif',
'position: fixed',
'font-size: 1em',
'z-index: 9999',
'bottom: 0px',
'right: 0px',
'border-top-left-radius: 5px',
'background-color: #1B2032',
'opacity: 0.4',
'margin: 0',
'color: white',
'text-align: center'
]
}
}, function () {
done();
});
}
/**
* Normalize all paths to be plain, paths with no leading './',
* relative to the process root, and with backslashes converted to
* forward slashes. Should work regardless of how the path was
* written. Accepts any number of parameters, and passes them along to
* path.resolve().
*
* This is intended to avoid all known limitations of gulp.watch().
*
* @param {...string} pathFragment - A directory, filename, or glob.
*/
function normalizePath() {
return path
.relative(
process.cwd(),
path.resolve.apply(this, arguments)
)
.replace(/\\/g, '/');
}
function paths() {
return config.paths;
}
function getConfiguredCleanOption() {
return config.cleanPublic;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment