|
| 1 | +const assemble = require('fabricator-assemble'); |
| 2 | +const autoprefixer = require('gulp-autoprefixer'); |
| 3 | +const browserSync = require('browser-sync'); |
| 4 | +const cssnano = require('gulp-cssnano'); |
| 5 | +const del = require('del'); |
| 6 | +const gulp = require('gulp'); |
| 7 | +const gulpif = require('gulp-if'); |
| 8 | +const gutil = require('gulp-util'); |
| 9 | +const imagemin = require('gulp-imagemin'); |
| 10 | +const notifier = require('node-notifier'); |
| 11 | +const runSequence = require('run-sequence'); |
| 12 | +const sass = require('gulp-sass'); |
| 13 | +const sourcemaps = require('gulp-sourcemaps'); |
| 14 | +const webpack = require('webpack'); |
| 15 | + |
| 16 | +const reload = browserSync.reload; |
| 17 | + |
| 18 | +// configuration |
| 19 | +const config = { |
| 20 | + templates: { |
| 21 | + src: ['src/templates/**/*', '!src/templates/layouts/**'], |
| 22 | + dest: 'dist', |
| 23 | + watch: ['src/templates/**/*', 'src/data/**/*.json'], |
| 24 | + layouts: 'src/templates/layouts/*', |
| 25 | + partials: ['src/templates/components/**/*'], |
| 26 | + data: 'src/data/**/*.{json,yml}', |
| 27 | + }, |
| 28 | + scripts: { |
| 29 | + src: './src/assets/scripts/main.js', |
| 30 | + dest: 'dist/assets/scripts', |
| 31 | + watch: 'src/assets/scripts/**/*', |
| 32 | + }, |
| 33 | + styles: { |
| 34 | + src: 'src/assets/styles/main.scss', |
| 35 | + dest: 'dist/assets/styles', |
| 36 | + watch: 'src/assets/styles/**/*', |
| 37 | + browsers: ['last 1 version'], |
| 38 | + }, |
| 39 | + images: { |
| 40 | + src: 'src/assets/images/**/*', |
| 41 | + dest: 'dist/assets/images', |
| 42 | + watch: 'src/assets/images/**/*', |
| 43 | + }, |
| 44 | + fonts: { |
| 45 | + src: 'src/assets/fonts/**/*', |
| 46 | + dest: 'dist/assets/fonts', |
| 47 | + watch: 'src/assets/fonts/**/*', |
| 48 | + }, |
| 49 | + data: { |
| 50 | + src: 'src/data/**/*', |
| 51 | + watch: 'src/data/**/*', |
| 52 | + }, |
| 53 | + dev: gutil.env.dev, |
| 54 | +}; |
| 55 | + |
| 56 | +// clean |
| 57 | +gulp.task('clean', del.bind(null, ['dist'])); |
| 58 | + |
| 59 | +// templates |
| 60 | +gulp.task('templates', (done) => { |
| 61 | + assemble({ |
| 62 | + layouts: config.templates.layouts, |
| 63 | + views: config.templates.src, |
| 64 | + materials: config.templates.partials, |
| 65 | + data: config.templates.data, |
| 66 | + keys: { |
| 67 | + views: 'templates', |
| 68 | + materials: 'components', |
| 69 | + }, |
| 70 | + dest: config.templates.dest, |
| 71 | + logErrors: config.dev, |
| 72 | + helpers: { |
| 73 | + // {{ default description "string of content used if description var is undefined" }} |
| 74 | + default: function defaultFn(...args) { |
| 75 | + return args.find(value => !!value); |
| 76 | + }, |
| 77 | + // {{ concat str1 "string 2" }} |
| 78 | + concat: function concat(...args) { |
| 79 | + return args.slice(0, args.length - 1).join(''); |
| 80 | + }, |
| 81 | + // {{> (dynamicPartial name) }} ---- name = 'nameOfComponent' |
| 82 | + dynamicPartial: function dynamicPartial(name) { |
| 83 | + return name; |
| 84 | + }, |
| 85 | + eq: function eq(v1, v2) { |
| 86 | + return v1 === v2; |
| 87 | + }, |
| 88 | + ne: function ne(v1, v2) { |
| 89 | + return v1 !== v2; |
| 90 | + }, |
| 91 | + and: function and(v1, v2) { |
| 92 | + return v1 && v2; |
| 93 | + }, |
| 94 | + or: function or(v1, v2) { |
| 95 | + return v1 || v2; |
| 96 | + }, |
| 97 | + not: function not(v1) { |
| 98 | + return !v1; |
| 99 | + }, |
| 100 | + gte: function gte(a, b) { |
| 101 | + return +a >= +b; |
| 102 | + }, |
| 103 | + lte: function lte(a, b) { |
| 104 | + return +a <= +b; |
| 105 | + }, |
| 106 | + plus: function plus(a, b) { |
| 107 | + return +a + +b; |
| 108 | + }, |
| 109 | + minus: function minus(a, b) { |
| 110 | + return +a - +b; |
| 111 | + }, |
| 112 | + divide: function divide(a, b) { |
| 113 | + return +a / +b; |
| 114 | + }, |
| 115 | + multiply: function multiply(a, b) { |
| 116 | + return +a * +b; |
| 117 | + }, |
| 118 | + abs: function abs(a) { |
| 119 | + return Math.abs(a); |
| 120 | + }, |
| 121 | + mod: function mod(a, b) { |
| 122 | + return +a % +b; |
| 123 | + }, |
| 124 | + }, |
| 125 | + }); |
| 126 | + done(); |
| 127 | +}); |
| 128 | + |
| 129 | +// scripts |
| 130 | +const webpackConfig = require('./webpack.config')(config); |
| 131 | + |
| 132 | +gulp.task('scripts', (done) => { |
| 133 | + webpack(webpackConfig, (err, stats) => { |
| 134 | + if (err) { |
| 135 | + gutil.log(gutil.colors.red(err())); |
| 136 | + } |
| 137 | + const result = stats.toJson(); |
| 138 | + if (result.errors.length) { |
| 139 | + result.errors.forEach((error) => { |
| 140 | + gutil.log(gutil.colors.red(error)); |
| 141 | + notifier.notify({ |
| 142 | + title: 'JS Build Error', |
| 143 | + message: error, |
| 144 | + }); |
| 145 | + }); |
| 146 | + } |
| 147 | + done(); |
| 148 | + }); |
| 149 | +}); |
| 150 | + |
| 151 | +// SASS styles |
| 152 | +gulp.task('styles', () => |
| 153 | + gulp.src(config.styles.src) |
| 154 | + .pipe(sourcemaps.init()) |
| 155 | + .pipe(sass({ |
| 156 | + includePaths: './node_modules', |
| 157 | + }).on('error', sass.logError)) |
| 158 | + .pipe(autoprefixer({ |
| 159 | + browsers: config.styles.browsers, |
| 160 | + })) |
| 161 | + .pipe(gulpif(!config.dev, cssnano({ autoprefixer: false }))) |
| 162 | + .pipe(sourcemaps.write()) |
| 163 | + .pipe(gulp.dest(config.styles.dest)) |
| 164 | + .pipe(gulpif(config.dev, reload({ stream: true })))); |
| 165 | + |
| 166 | +// images |
| 167 | +gulp.task('images', () => |
| 168 | + gulp.src(config.images.src) |
| 169 | + .pipe(imagemin({ |
| 170 | + progressive: true, |
| 171 | + interlaced: true, |
| 172 | + })) |
| 173 | + .pipe(gulp.dest(config.images.dest))); |
| 174 | + |
| 175 | +// fonts |
| 176 | +gulp.task('fonts', () => |
| 177 | + gulp.src(config.fonts.src).pipe(gulp.dest(config.fonts.dest))); |
| 178 | + |
| 179 | +// data |
| 180 | +gulp.task('data', () => |
| 181 | + gulp.src(config.data.src)) |
| 182 | + |
| 183 | +// server |
| 184 | +gulp.task('serve', () => { |
| 185 | + browserSync({ |
| 186 | + server: { |
| 187 | + baseDir: config.templates.dest, |
| 188 | + }, |
| 189 | + notify: false, |
| 190 | + logPrefix: 'BrowserSync', |
| 191 | + }); |
| 192 | + |
| 193 | + gulp.task('templates:watch', ['templates'], reload); |
| 194 | + gulp.watch(config.templates.watch, ['templates:watch']); |
| 195 | + gulp.task('styles:watch', ['styles']); |
| 196 | + gulp.watch(config.styles.watch, ['styles:watch']); |
| 197 | + gulp.task('scripts:watch', ['scripts'], reload); |
| 198 | + gulp.watch(config.scripts.watch, ['scripts:watch']); |
| 199 | + gulp.task('images:watch', ['images'], reload); |
| 200 | + gulp.watch(config.images.watch, ['images:watch']); |
| 201 | + gulp.task('fonts:watch', ['fonts'], reload); |
| 202 | + gulp.watch(config.fonts.watch, ['fonts:watch']); |
| 203 | + gulp.task('data:watch', ['templates'], reload); |
| 204 | + gulp.watch(config.data.watch, ['data:watch']); |
| 205 | +}); |
| 206 | + |
| 207 | +// default build task |
| 208 | +gulp.task('default', ['clean'], () => { |
| 209 | + const tasks = [ |
| 210 | + 'templates', |
| 211 | + 'scripts', |
| 212 | + 'styles', |
| 213 | + 'images', |
| 214 | + 'fonts', |
| 215 | + 'data', |
| 216 | + ]; |
| 217 | + |
| 218 | + // run build |
| 219 | + runSequence(tasks, () => { |
| 220 | + if (config.dev) { |
| 221 | + gulp.start('serve'); |
| 222 | + } |
| 223 | + }); |
| 224 | +}); |
0 commit comments