diff options
Diffstat (limited to 'gulpfile.js')
-rw-r--r-- | gulpfile.js/build.js | 67 | ||||
-rw-r--r-- | gulpfile.js/format.js | 10 | ||||
-rw-r--r-- | gulpfile.js/index.js (renamed from gulpfile.js) | 8 | ||||
-rw-r--r-- | gulpfile.js/lib/export-tasks.js | 4 | ||||
-rw-r--r-- | gulpfile.js/lib/gulp-prettier-eslint.js | 42 | ||||
-rw-r--r-- | gulpfile.js/lib/task.js | 15 | ||||
-rw-r--r-- | gulpfile.js/lint-css.js | 7 | ||||
-rw-r--r-- | gulpfile.js/lint-js.js | 12 | ||||
-rw-r--r-- | gulpfile.js/pack.js | 10 | ||||
-rw-r--r-- | gulpfile.js/preview-pages.js | 81 | ||||
-rw-r--r-- | gulpfile.js/preview-serve.js | 23 | ||||
-rw-r--r-- | gulpfile.js/remove.js | 8 |
12 files changed, 283 insertions, 4 deletions
diff --git a/gulpfile.js/build.js b/gulpfile.js/build.js new file mode 100644 index 0000000..8db878d --- /dev/null +++ b/gulpfile.js/build.js @@ -0,0 +1,67 @@ +'use strict' + +const autoprefixer = require('autoprefixer') +const browserify = require('browserify') +const buffer = require('vinyl-buffer') +const concat = require('gulp-concat') +const cssnano = require('cssnano') +const fs = require('fs-extra') +const imagemin = require('gulp-imagemin') +const merge = require('merge-stream') +const { obj: map } = require('through2') +const path = require('path') +const postcss = require('gulp-postcss') +const postcssCalc = require('postcss-calc') +const postcssImport = require('postcss-import') +const postcssUrl = require('postcss-url') +const postcssVar = require('postcss-custom-properties') +const uglify = require('gulp-uglify') +const vfs = require('vinyl-fs') + +module.exports = (src, dest, preview) => () => { + const opts = { base: src, cwd: src } + const postcssPlugins = [ + postcssImport(), + postcssUrl([ + { + filter: '**/~typeface-*/files/*', + url: (asset) => { + const relpath = asset.pathname.substr(1) + const abspath = path.resolve('node_modules', relpath) + const basename = path.basename(abspath) + const destpath = path.join(dest, 'font', basename) + if (!fs.pathExists(destpath)) fs.copy(abspath, destpath) + return path.join('..', 'font', basename) + }, + }, + ]), + postcssVar({ preserve: preview ? 'preserve-computed' : false }), + postcssCalc(), + autoprefixer({ browsers: ['last 2 versions'] }), + preview ? () => {} : cssnano({ preset: 'default' }), + ] + + return merge( + vfs + .src('js/+([0-9])-*.js', opts) + .pipe(uglify()) + .pipe(concat('js/site.js')), + vfs + .src('js/vendor/*.js', Object.assign({ read: false }, opts)) + .pipe( + // see https://gulpjs.org/recipes/browserify-multiple-destination.html + map((file, enc, next) => { + file.contents = browserify(file.relative, { basedir: src, detectGlobals: false }).bundle() + next(null, file) + }) + ) + .pipe(buffer()) + .pipe(uglify()), + vfs.src('css/site.css', opts).pipe(postcss(postcssPlugins)), + vfs.src('font/*.woff*(2)', opts), + vfs.src('img/**/*.{jpg,ico,png,svg}', opts).pipe(imagemin()), + vfs.src('helpers/*.js', opts), + vfs.src('layouts/*.hbs', opts), + vfs.src('partials/*.hbs', opts) + ).pipe(vfs.dest(dest)) +} diff --git a/gulpfile.js/format.js b/gulpfile.js/format.js new file mode 100644 index 0000000..c95d506 --- /dev/null +++ b/gulpfile.js/format.js @@ -0,0 +1,10 @@ +'use strict' + +const prettier = require('./lib/gulp-prettier-eslint') +const vfs = require('vinyl-fs') + +module.exports = (files) => () => + vfs + .src(files) + .pipe(prettier()) + .pipe(vfs.dest((file) => file.base)) diff --git a/gulpfile.js b/gulpfile.js/index.js index d769ad5..9b9bd91 100644 --- a/gulpfile.js +++ b/gulpfile.js/index.js @@ -2,9 +2,9 @@ const { parallel, series, tree } = require('gulp') const camelcase = (name) => name.replace(/[-]./g, (m) => m.substr(1).toUpperCase()) -const exportTasks = require('./tasks/lib/export-tasks') -const task = require('./tasks/lib/task') -const taskFns = require('require-directory')(module, './tasks', { recurse: false, rename: camelcase }) +const exportTasks = require('./lib/export-tasks') +const task = require('./lib/task') +const taskFns = require('require-directory')(module, '.', { recurse: false, rename: camelcase }) const path = require('path') const bundleName = 'ui' @@ -16,7 +16,7 @@ const destDir = path.join(previewSiteDestDir, '_') const { reload: livereload } = process.env.LIVERELOAD === 'true' ? require('gulp-connect') : {} const cssFileGlobs = path.join(srcDir, 'css/**/*.css') -const jsFileGlobs = ['gulpfile.js', 'tasks/**/*.js', path.join(srcDir, '{helpers,js}/**/*.js')] +const jsFileGlobs = ['gulpfile.js/**/*.js', path.join(srcDir, '{helpers,js}/**/*.js')] const { remove, lintCss, lintJs, format, build, pack, previewPages, previewServe } = taskFns diff --git a/gulpfile.js/lib/export-tasks.js b/gulpfile.js/lib/export-tasks.js new file mode 100644 index 0000000..834cd9e --- /dev/null +++ b/gulpfile.js/lib/export-tasks.js @@ -0,0 +1,4 @@ +'use strict' + +module.exports = (...tasks) => + tasks.reduce((acc, task) => (acc[task.displayName || task.name] = task) && acc, { default: tasks.shift() }) diff --git a/gulpfile.js/lib/gulp-prettier-eslint.js b/gulpfile.js/lib/gulp-prettier-eslint.js new file mode 100644 index 0000000..dca0a74 --- /dev/null +++ b/gulpfile.js/lib/gulp-prettier-eslint.js @@ -0,0 +1,42 @@ +'use strict' + +const { obj: map } = require('through2') +const PluginError = require('plugin-error') +const prettierEslint = require('prettier-eslint') + +module.exports = () => { + const report = { changed: 0, unchanged: 0 } + return map(format).on('finish', () => { + if (report.changed > 0) { + const changed = 'formatted ' + .concat(report.changed) + .concat(' file') + .concat(report.changed === 1 ? '' : 's') + const unchanged = 'left ' + .concat(report.unchanged) + .concat(' file') + .concat(report.unchanged === 1 ? '' : 's') + .concat(' unchanged') + console.log(`prettier-eslint: ${changed}; ${unchanged}`) + } else { + console.log(`prettier-eslint: left ${report.unchanged} file${report.unchanged === 1 ? '' : 's'} unchanged`) + } + }) + + function format (file, enc, next) { + if (file.isNull()) return next() + if (file.isStream()) return next(new PluginError('gulp-prettier-eslint', 'Streaming not supported')) + + const input = file.contents.toString() + const output = prettierEslint({ text: input, filePath: file.path }) + + if (input === output) { + report.unchanged += 1 + } else { + report.changed += 1 + file.contents = Buffer.from(output) + } + + next(null, file) + } +} diff --git a/gulpfile.js/lib/task.js b/gulpfile.js/lib/task.js new file mode 100644 index 0000000..aa4f9d1 --- /dev/null +++ b/gulpfile.js/lib/task.js @@ -0,0 +1,15 @@ +'use strict' + +const metadata = require('undertaker/lib/helpers/metadata') + +module.exports = ({ name, desc, anon, then: fn }) => { + if (name) { + const displayName = fn.displayName + if (displayName === '<series>' || displayName === '<parallel>') { + metadata.get(fn).tree.label = `${displayName} ${name}` + } + fn.displayName = name + } + if (desc) fn.description = desc + return fn +} diff --git a/gulpfile.js/lint-css.js b/gulpfile.js/lint-css.js new file mode 100644 index 0000000..5cad763 --- /dev/null +++ b/gulpfile.js/lint-css.js @@ -0,0 +1,7 @@ +'use strict' + +const stylelint = require('gulp-stylelint') +const vfs = require('vinyl-fs') + +module.exports = (files) => () => + vfs.src(files).pipe(stylelint({ reporters: [{ formatter: 'string', console: true }] })) diff --git a/gulpfile.js/lint-js.js b/gulpfile.js/lint-js.js new file mode 100644 index 0000000..ef4f3c9 --- /dev/null +++ b/gulpfile.js/lint-js.js @@ -0,0 +1,12 @@ +'use strict' + +const eslint = require('gulp-eslint') +const vfs = require('vinyl-fs') + +module.exports = (files) => (done) => + vfs + .src(files) + .pipe(eslint()) + .pipe(eslint.format()) + .pipe(eslint.failAfterError()) + .on('error', done) diff --git a/gulpfile.js/pack.js b/gulpfile.js/pack.js new file mode 100644 index 0000000..7c9d3ae --- /dev/null +++ b/gulpfile.js/pack.js @@ -0,0 +1,10 @@ +'use strict' + +const vfs = require('vinyl-fs') +const zip = require('gulp-vinyl-zip') + +module.exports = (src, dest, bundleName) => () => + vfs + .src('**/*', { base: src, cwd: src }) + .pipe(zip.zip(`${bundleName}-bundle.zip`)) + .pipe(vfs.dest(dest)) diff --git a/gulpfile.js/preview-pages.js b/gulpfile.js/preview-pages.js new file mode 100644 index 0000000..abc8b98 --- /dev/null +++ b/gulpfile.js/preview-pages.js @@ -0,0 +1,81 @@ +'use strict' + +const fs = require('fs-extra') +const handlebars = require('handlebars') +const { obj: map } = require('through2') +const path = require('path') +const requireFromString = require('require-from-string') +const vfs = require('vinyl-fs') +const yaml = require('js-yaml') + +module.exports = (src, dest, siteSrc, siteDest, onComplete) => () => + Promise.all([loadSampleUiModel(siteSrc), compileLayouts(src), registerPartials(src), registerHelpers(src)]).then( + ([uiModel, layouts]) => + vfs + .src('**/*.html', { base: siteSrc, cwd: siteSrc }) + .pipe( + map((file, enc, next) => { + const compiledLayout = layouts[file.stem === '404' ? '404.hbs' : 'default.hbs'] + const siteRootPath = path.relative(path.dirname(file.path), path.resolve(siteSrc)) + uiModel.env = process.env + uiModel.siteRootPath = siteRootPath + uiModel.siteRootUrl = path.join(siteRootPath, 'index.html') + uiModel.uiRootPath = path.join(siteRootPath, '_') + uiModel.page.contents = file.contents.toString().trim() + file.contents = Buffer.from(compiledLayout(uiModel)) + next(null, file) + }) + ) + .pipe(vfs.dest(siteDest)) + .pipe(onComplete ? onComplete() : map((file, enc, next) => next())) + ) + +function loadSampleUiModel (siteSrc) { + return fs.readFile(path.join(siteSrc, 'ui-model.yml'), 'utf8').then((contents) => yaml.safeLoad(contents)) +} + +function registerPartials (src) { + return new Promise((resolve, reject) => + vfs + .src('partials/*.hbs', { base: src, cwd: src }) + .pipe( + map((file, enc, next) => { + handlebars.registerPartial(file.stem, file.contents.toString()) + next() + }) + ) + .on('error', reject) + .on('finish', resolve) + ) +} + +function registerHelpers (src) { + return new Promise((resolve, reject) => + vfs + .src('helpers/*.js', { base: src, cwd: src }) + .pipe( + map((file, enc, next) => { + handlebars.registerHelper(file.stem, requireFromString(file.contents.toString())) + next() + }) + ) + .on('error', reject) + .on('finish', resolve) + ) +} + +function compileLayouts (src) { + const layouts = {} + return new Promise((resolve, reject) => + vfs + .src('layouts/*.hbs', { base: src, cwd: src }) + .pipe( + map((file, enc, next) => { + layouts[file.basename] = handlebars.compile(file.contents.toString(), { preventIndent: true }) + next() + }) + ) + .on('error', reject) + .on('finish', () => resolve(layouts)) + ) +} diff --git a/gulpfile.js/preview-serve.js b/gulpfile.js/preview-serve.js new file mode 100644 index 0000000..9dcf39e --- /dev/null +++ b/gulpfile.js/preview-serve.js @@ -0,0 +1,23 @@ +'use strict' + +const chokidar = require('chokidar') +const connect = require('gulp-connect') + +module.exports = (serveDir, opts = {}) => (done) => { + const watch = opts.watch + delete opts.watch + opts = Object.assign({ root: serveDir }, opts) + let onStart + if (watch && watch.src && watch.onChange) { + onStart = () => + chokidar + .watch(watch.src, { ignoreInitial: true }) + .on('add', watch.onChange) + .on('change', watch.onChange) + .on('unlink', watch.onChange) + } + connect.server(opts, function () { + this.server.on('close', done) + if (onStart) onStart() + }) +} diff --git a/gulpfile.js/remove.js b/gulpfile.js/remove.js new file mode 100644 index 0000000..3f71eec --- /dev/null +++ b/gulpfile.js/remove.js @@ -0,0 +1,8 @@ +'use strict' + +const fs = require('fs-extra') +const { obj: map } = require('through2') +const vfs = require('vinyl-fs') + +module.exports = (files) => () => + vfs.src(files, { allowEmpty: true }).pipe(map((file, enc, next) => fs.remove(file.path, next))) |