summaryrefslogtreecommitdiffstats
path: root/gulpfile.js
diff options
context:
space:
mode:
Diffstat (limited to 'gulpfile.js')
-rw-r--r--gulpfile.js/build.js67
-rw-r--r--gulpfile.js/format.js10
-rw-r--r--gulpfile.js/index.js (renamed from gulpfile.js)8
-rw-r--r--gulpfile.js/lib/export-tasks.js4
-rw-r--r--gulpfile.js/lib/gulp-prettier-eslint.js42
-rw-r--r--gulpfile.js/lib/task.js15
-rw-r--r--gulpfile.js/lint-css.js7
-rw-r--r--gulpfile.js/lint-js.js12
-rw-r--r--gulpfile.js/pack.js10
-rw-r--r--gulpfile.js/preview-pages.js81
-rw-r--r--gulpfile.js/preview-serve.js23
-rw-r--r--gulpfile.js/remove.js8
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)))